routes_zichan.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. import { Hono } from "hono";
  2. import debug from "debug";
  3. import type {
  4. ZichanInfo,
  5. } from "../client/share/monitorTypes.ts";
  6. import {
  7. DeviceCategory,
  8. DeviceStatus,
  9. } from "../client/share/monitorTypes.ts";
  10. import type { Variables, WithAuth } from "./middlewares.ts";
  11. const log = {
  12. api: debug("d8d:zichan:api"),
  13. };
  14. // 创建资产管理路由
  15. export function createZichanRoutes(withAuth: WithAuth) {
  16. const zichanRoutes = new Hono<{ Variables: Variables }>();
  17. // 获取资产列表
  18. zichanRoutes.get("/", withAuth, async (c) => {
  19. try {
  20. const apiClient = c.get('apiClient');
  21. // 获取分页参数
  22. const page = Number(c.req.query("page")) || 1;
  23. const limit = Number(c.req.query("limit")) || 10;
  24. const offset = (page - 1) * limit;
  25. // 获取筛选参数
  26. const assetName = c.req.query("asset_name");
  27. const categoryParam = c.req.query("device_category");
  28. const statusParam = c.req.query("device_status");
  29. // 构建查询
  30. let query = apiClient.database
  31. .table("zichan_info")
  32. .where("is_deleted", 0)
  33. .orderBy("id", "desc");
  34. // 应用筛选条件
  35. if (assetName) {
  36. query = query.where("asset_name", "like", `%${assetName}%`);
  37. }
  38. if (categoryParam) {
  39. const category = Number(categoryParam);
  40. if (
  41. !isNaN(category) &&
  42. Object.values(DeviceCategory).includes(category)
  43. ) {
  44. query = query.where("device_category", category);
  45. }
  46. }
  47. if (statusParam) {
  48. const status = Number(statusParam);
  49. if (!isNaN(status) && Object.values(DeviceStatus).includes(status)) {
  50. query = query.where("device_status", status);
  51. }
  52. }
  53. // 克隆查询以获取总数
  54. const countQuery = query.clone();
  55. // 执行分页查询
  56. const assets = await query.limit(limit).offset(offset);
  57. // 获取总数
  58. const count = await countQuery.count();
  59. return c.json({
  60. data: assets,
  61. pagination: {
  62. total: Number(count),
  63. current: page,
  64. pageSize: limit,
  65. totalPages: Math.ceil(Number(count) / limit),
  66. },
  67. });
  68. } catch (error) {
  69. log.api("获取资产列表失败:", error);
  70. return c.json({ error: "获取资产列表失败" }, 500);
  71. }
  72. });
  73. // 获取单个资产
  74. zichanRoutes.get("/:id", withAuth, async (c) => {
  75. try {
  76. const id = Number(c.req.param("id"));
  77. if (!id || isNaN(id)) {
  78. return c.json({ error: "无效的资产ID" }, 400);
  79. }
  80. const apiClient = c.get('apiClient');
  81. const [asset] = await apiClient.database
  82. .table("zichan_info")
  83. .where({ id, is_deleted: 0 });
  84. if (!asset) {
  85. return c.json({ error: "资产不存在" }, 404);
  86. }
  87. return c.json(asset);
  88. } catch (error) {
  89. log.api("获取资产详情失败:", error);
  90. return c.json({ error: "获取资产详情失败" }, 500);
  91. }
  92. });
  93. // 创建资产
  94. zichanRoutes.post("/", withAuth, async (c) => {
  95. try {
  96. const assetData = (await c.req.json()) as Partial<ZichanInfo>;
  97. // 验证必填字段
  98. if (!assetData.asset_name) {
  99. return c.json({ error: "资产名称不能为空" }, 400);
  100. }
  101. const apiClient = c.get('apiClient');
  102. const [id] = await apiClient.database
  103. .table("zichan_info")
  104. .insert(assetData);
  105. // 获取创建的资产
  106. const [createdAsset] = await apiClient.database
  107. .table("zichan_info")
  108. .where("id", id);
  109. return c.json({
  110. message: "资产创建成功",
  111. data: createdAsset,
  112. });
  113. } catch (error) {
  114. log.api("创建资产失败:", error);
  115. return c.json({ error: "创建资产失败" }, 500);
  116. }
  117. });
  118. // 更新资产
  119. zichanRoutes.put("/:id", withAuth, async (c) => {
  120. try {
  121. const id = Number(c.req.param("id"));
  122. if (!id || isNaN(id)) {
  123. return c.json({ error: "无效的资产ID" }, 400);
  124. }
  125. const assetData = (await c.req.json()) as Partial<ZichanInfo>;
  126. // 验证必填字段
  127. if (!assetData.asset_name) {
  128. return c.json({ error: "资产名称不能为空" }, 400);
  129. }
  130. const apiClient = c.get('apiClient');
  131. // 检查资产是否存在
  132. const [existingAsset] = await apiClient.database
  133. .table("zichan_info")
  134. .where({ id, is_deleted: 0 });
  135. if (!existingAsset) {
  136. return c.json({ error: "资产不存在" }, 404);
  137. }
  138. // 更新资产
  139. await apiClient.database
  140. .table("zichan_info")
  141. .where("id", id)
  142. .update({
  143. ...assetData,
  144. updated_at: apiClient.database.fn.now(),
  145. });
  146. // 获取更新后的资产
  147. const [updatedAsset] = await apiClient.database
  148. .table("zichan_info")
  149. .where("id", id);
  150. return c.json({
  151. message: "资产更新成功",
  152. data: updatedAsset,
  153. });
  154. } catch (error) {
  155. log.api("更新资产失败:", error);
  156. return c.json({ error: "更新资产失败" }, 500);
  157. }
  158. });
  159. // 删除资产(软删除)
  160. zichanRoutes.delete("/:id", withAuth, async (c) => {
  161. try {
  162. const id = Number(c.req.param("id"));
  163. if (!id || isNaN(id)) {
  164. return c.json({ error: "无效的资产ID" }, 400);
  165. }
  166. const apiClient = c.get('apiClient');
  167. // 检查资产是否存在
  168. const [existingAsset] = await apiClient.database
  169. .table("zichan_info")
  170. .where({ id, is_deleted: 0 });
  171. if (!existingAsset) {
  172. return c.json({ error: "资产不存在" }, 404);
  173. }
  174. // 软删除资产
  175. await apiClient.database.table("zichan_info").where("id", id).update({
  176. is_deleted: 1,
  177. updated_at: apiClient.database.fn.now(),
  178. });
  179. return c.json({
  180. message: "资产删除成功",
  181. id,
  182. });
  183. } catch (error) {
  184. log.api("删除资产失败:", error);
  185. return c.json({ error: "删除资产失败" }, 500);
  186. }
  187. });
  188. return zichanRoutes;
  189. }