index.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import express from "express";
  2. import mysql from "mysql2/promise";
  3. import timeout from "connect-timeout";
  4. import bodyParser from "body-parser";
  5. const app = express();
  6. const PORT = 3000;
  7. // 设置请求超时,单位为毫秒(比如:设置 30 秒超时)
  8. app.use(timeout("30s"));
  9. app.use(bodyParser.json()); // 在请求处理之前,先解析JSON
  10. // 处理超时请求
  11. app.use((req, res, next) => {
  12. if (req.timedout) {
  13. return res.status(408).send("Request Timeout");
  14. }
  15. next();
  16. });
  17. // 获取表和字段信息
  18. app.get("/tables", async (req, res) => {
  19. let pool;
  20. try {
  21. const { IP, host, baseName, username, password } = req.query;
  22. // 数据库连接配置
  23. pool = mysql.createPool({
  24. host: IP,
  25. user: username,
  26. password: password,
  27. database: baseName,
  28. port: host,
  29. });
  30. const connection = await pool.getConnection();
  31. // 获取所有表名
  32. const [tables] = await connection.query("SHOW TABLES");
  33. const tableFieldMap = {};
  34. for (const table of tables) {
  35. const tableName = `${Object.values(table)[0]}`;
  36. // 加反引号以支持包含特殊字符的表名
  37. const [fields] = await connection.query("DESCRIBE `" + tableName + "`");
  38. tableFieldMap[tableName] = fields.map((field) => field.Field);
  39. }
  40. connection.release();
  41. res.json(tableFieldMap);
  42. } catch (error) {
  43. res.status(500).send("请检查填写的数据库数据是否有误: " + error.message);
  44. } finally {
  45. // 确保关闭数据库连接池
  46. if (pool) {
  47. await pool.end();
  48. }
  49. }
  50. });
  51. app.post("/filterTablesData", async (req, res) => {
  52. let pool;
  53. try {
  54. const { IP, host, baseName, username, password } = req.body.database;
  55. const filterData = req.body.filterData;
  56. // 数据库连接配置
  57. pool = mysql.createPool({
  58. host: IP,
  59. user: username,
  60. password: password,
  61. database: baseName,
  62. port: host,
  63. });
  64. const connection = await pool.getConnection();
  65. const resultData = {};
  66. for (const item of filterData) {
  67. const parentNode = item.parentNode; // 数据表名
  68. if (!parentNode) {
  69. console.warn(
  70. "parentNode is undefined or null. Skipping this item:",
  71. item
  72. );
  73. continue; // 跳过无效的项
  74. }
  75. const checkChildNode = item.checkChildNode; // 要查询的字段
  76. // 检查表是否存在
  77. const [tables] = await connection.query("SHOW TABLES");
  78. const tableNames = tables.map((row) =>
  79. Object.values(row)[0].toLowerCase()
  80. );
  81. if (!tableNames.includes(parentNode.toLowerCase())) {
  82. continue;
  83. }
  84. // 获取表字段信息
  85. const [columns] = await connection.query(
  86. `SHOW COLUMNS FROM \`${parentNode}\``
  87. );
  88. const tableFields = columns.map((column) => column.Field);
  89. // 过滤有效字段
  90. const validFields = checkChildNode.filter((field) =>
  91. tableFields.includes(field)
  92. );
  93. if (validFields.length === 0) {
  94. continue;
  95. }
  96. // 动态查询字段的数据
  97. const sqlQuery = `SELECT ${validFields
  98. .map((field) => `\`${field}\``)
  99. .join(", ")} FROM \`${parentNode}\` LIMIT 500`;
  100. console.log("Generated SQL Query:", sqlQuery);
  101. const [rows] = await connection.query(sqlQuery);
  102. // 保存结果
  103. resultData[parentNode] = rows;
  104. }
  105. connection.release();
  106. res.json(resultData);
  107. } catch (error) {
  108. console.error(error);
  109. res.status(500).send(`数据库报错: ${error.message}`);
  110. } finally {
  111. if (pool) {
  112. await pool.end();
  113. }
  114. }
  115. });
  116. app.listen(PORT, () => {
  117. console.log(`Server is running on http://localhost:${PORT}`);
  118. });