rui.jiang 5 hónapja
szülő
commit
3bf02c55e0

+ 44 - 22
sever/index.js

@@ -21,6 +21,7 @@ app.get("/tables", async (req, res) => {
   let pool;
   try {
     const { IP, host, baseName, username, password } = req.query;
+
     // 数据库连接配置
     pool = mysql.createPool({
       host: IP,
@@ -29,19 +30,27 @@ app.get("/tables", async (req, res) => {
       database: baseName,
       port: host,
     });
+
     const connection = await pool.getConnection();
+
+    // 获取所有表名
     const [tables] = await connection.query("SHOW TABLES");
+
     const tableFieldMap = {};
+
     for (const table of tables) {
-      const tableName = Object.values(table)[0];
-      const [fields] = await connection.query(`DESCRIBE ${tableName}`);
+      const tableName = `${Object.values(table)[0]}`;
+
+      // 加反引号以支持包含特殊字符的表名
+      const [fields] = await connection.query("DESCRIBE `" + tableName + "`");
+
       tableFieldMap[tableName] = fields.map((field) => field.Field);
     }
+
     connection.release();
     res.json(tableFieldMap);
   } catch (error) {
-    // console.error("Error fetching database structure:", error);
-    res.status(500).send("请检查填写的数据库数据是否有误" + error);
+    res.status(500).send("请检查填写的数据库数据是否有误: " + error.message);
   } finally {
     // 确保关闭数据库连接池
     if (pool) {
@@ -49,67 +58,80 @@ app.get("/tables", async (req, res) => {
     }
   }
 });
+
 app.post("/filterTablesData", async (req, res) => {
+  let pool;
   try {
-    console.log(req.params, req.body, "req.query.filterData");
     const { IP, host, baseName, username, password } = req.body.database;
     const filterData = req.body.filterData;
+
     // 数据库连接配置
-    const pool = mysql.createPool({
+    pool = mysql.createPool({
       host: IP,
       user: username,
       password: password,
       database: baseName,
       port: host,
     });
-    // 获取数据库连接;
+
     const connection = await pool.getConnection();
-    // 用于存储最终查询结果
     const resultData = {};
-    // 遍历 filterData
+
     for (const item of filterData) {
       const parentNode = item.parentNode; // 数据表名
+      if (!parentNode) {
+        console.warn(
+          "parentNode is undefined or null. Skipping this item:",
+          item
+        );
+        continue; // 跳过无效的项
+      }
       const checkChildNode = item.checkChildNode; // 要查询的字段
 
       // 检查表是否存在
       const [tables] = await connection.query("SHOW TABLES");
-      const tableNames = tables.map((row) => Object.values(row)[0]);
-      if (!tableNames.includes(parentNode)) {
-        continue; // 如果表不存在,跳过
+      const tableNames = tables.map((row) =>
+        Object.values(row)[0].toLowerCase()
+      );
+      if (!tableNames.includes(parentNode.toLowerCase())) {
+        continue;
       }
 
       // 获取表字段信息
       const [columns] = await connection.query(
-        `SHOW COLUMNS FROM ${parentNode}`
+        `SHOW COLUMNS FROM \`${parentNode}\``
       );
       const tableFields = columns.map((column) => column.Field);
 
-      // 过滤存在的字段
+      // 过滤有效字段
       const validFields = checkChildNode.filter((field) =>
         tableFields.includes(field)
       );
       if (validFields.length === 0) {
-        continue; // 如果没有匹配的字段,跳过
+        continue;
       }
 
       // 动态查询字段的数据
-      const sqlQuery = `SELECT ${validFields.join(
-        ", "
-      )} FROM ${parentNode} LIMIT 100`; // 限制查询 100 条数据
+      const sqlQuery = `SELECT ${validFields
+        .map((field) => `\`${field}\``)
+        .join(", ")} FROM \`${parentNode}\` LIMIT 500`;
+      console.log("Generated SQL Query:", sqlQuery);
       const [rows] = await connection.query(sqlQuery);
-
       // 保存结果
       resultData[parentNode] = rows;
     }
-    // 释放连接
     connection.release();
-    // 返回最终数据
     res.json(resultData);
   } catch (error) {
     console.error(error);
-    res.status(500).send("Error fetching data from database");
+    res.status(500).send(`数据库报错: ${error.message}`);
+  } finally {
+    if (pool) {
+      await pool.end();
+    }
   }
 });
+
 app.listen(PORT, () => {
   console.log(`Server is running on http://localhost:${PORT}`);
 });

+ 3 - 2
src/main.js

@@ -73,13 +73,14 @@ Vue.prototype.$formatDateTWO = function (timestamp) {
 // 路由导航守卫
 router.beforeEach((to, from, next) => {
   if (from.path === "/home/performance/customAnalysis") {
-    store.commit("dragChart/clearchart");
+    if (to.path !== "/home/performance/luckySheet") {
+      store.commit("dragChart/clearchart");
+    }
   }
   next();
 });
 // 监听页面刷新或关闭事件
 window.addEventListener("beforeunload", () => {
-  console.log("调用了dragChart/clearchart");
   // 调用清空 Vuex 仓库的 Action
   store.commit("dragChart/clearchart");
 });

+ 12 - 2
src/views/laserRangeFinder/index.vue

@@ -6,7 +6,7 @@
           <template slot="title">
             <div class="titleLeft">数据筛选</div>
             <div class="titleRight">
-              <el-button type="primary" @click.stop="onSubmit" size="small">
+              <el-button type="primary" @click.stop="getTableData" size="small">
                 查询
               </el-button>
               <el-button
@@ -171,6 +171,8 @@ import MultilevelTable from "./components/MultilevelTable.vue";
 import InitCharts from "./components/initCharts.vue";
 import CylinderOfTower from "./components/CylinderOfTower.vue";
 import PlotOfFit from "./components/PlotOfFit.vue";
+import axios from "axios";
+//
 export default {
   data() {
     return {
@@ -190,7 +192,6 @@ export default {
       labels: ["2024/1/1", "2024/1/2", "2024/1/3", "2024/1/4"], // 假设是时间轴数据
       currentIndex: 0,
       tableData: [], // 假设是来自父组件的数据
-
       company: "",
       companyoptions: [],
       unitvalue: "",
@@ -217,6 +218,15 @@ export default {
     this.GETtree();
   },
   methods: {
+    //获取表格数据接口
+    async getTableData() {
+      try {
+        console.log(this.formInline, "formInline");
+        const res = await axios.post("/WZLapi/laserData/getLaserData");
+      } catch (err) {
+        this.$message.error(err);
+      }
+    },
     // 获取风场
     async GETtree() {
       try {

+ 22 - 18
src/views/performance/components/custonAsCom/dragChart/components/chartsData.vue

@@ -135,26 +135,30 @@ export default {
         node.level === 1
           ? h("span", [
               h(
-                "span",
-                data.label
-                // [
-                //   // "el-checkbox",
-                //   // {
-                //   //   props: {
-                //   //     value: node.checked,
-                //   //     indeterminate: node.indeterminate, // 用于半选状态
-                //   //   },
-                //   //   on: {
-                //   //     change: (val) => {
-                //   //       this.handleParentNodeChange(node, val);
-                //   //     },
-                //   //   },
-                //   // },
-                //   data.label
-                // ]
+                "el-tooltip",
+                {
+                  props: {
+                    content: data.label, // 设置 tooltip 的内容为当前节点的 label
+                    placement: "top", // 设置提示框位置,可根据需要调整
+                  },
+                },
+                [
+                  h("span", data.label), // label 文本
+                ]
               ),
             ])
-          : h("span", data.label),
+          : h(
+              "el-tooltip",
+              {
+                props: {
+                  content: data.label, // 设置 tooltip 的内容为当前节点的 label
+                  placement: "top", // 设置提示框位置,可根据需要调整
+                },
+              },
+              [
+                h("span", data.label), // label 文本
+              ]
+            ),
       ]);
     },
   },

+ 101 - 49
src/views/performance/components/custonAsCom/luckySheet.vue

@@ -26,7 +26,6 @@
 
 <script>
 import luckysheet from "luckysheet";
-// import LuckyExcel from "luckyexcel";
 import {
   getDataFromIndexedDB,
   storeSetData,
@@ -47,26 +46,26 @@ export default {
   methods: {
     async initSheetData() {
       const jsonData = await getDataFromIndexedDB();
-      console.log(
-        [...jsonData].filter((item) => item.fileId == this.$route.query.id)[0],
-        "this.$route.query.id"
-      );
-      this.sheetName = [...jsonData].filter(
-        (item) => item.fileId == this.$route.query.id
-      )[0].fileOldName;
-      // 1. 动态提取表头
-      const headers = Object.keys(
-        [...jsonData].filter((item) => item.fileId == this.$route.query.id)[0]
-          .fileData[0]
-      );
-      // 2. 将 JSON 数据转换为二维数组格式
-      const formattedData = [...jsonData]
-        .filter((item) => item.fileId == this.$route.query.id)[0]
-        .fileData.map((item) => headers.map((header) => item[header]));
-      // 3. 将表头插入到数据的第一行
-      formattedData.unshift(headers);
-      //4.  将 JSON 数据转换为 Luckysheet 格式
-      this.initLuckySheet(formattedData);
+      console.log(jsonData, "jsonData");
+      if (jsonData && jsonData.length > 0) {
+        this.sheetName = [...jsonData].filter(
+          (item) => item.fileId == this.$route.query.id
+        )[0]?.fileOldName;
+
+        // 1. 动态提取表头
+        const headers = Object.keys(
+          [...jsonData].filter((item) => item.fileId == this.$route.query.id)[0]
+            .fileData[0]
+        );
+        // 2. 将 JSON 数据转换为二维数组格式
+        const formattedData = [...jsonData]
+          .filter((item) => item.fileId == this.$route.query.id)[0]
+          .fileData.map((item) => headers.map((header) => item[header]));
+        // 3. 将表头插入到数据的第一行
+        formattedData.unshift(headers);
+        //4.  将 JSON 数据转换为 Luckysheet 格式
+        this.initLuckySheet(formattedData);
+      }
     },
     initLuckySheet(formattedData) {
       const options = {
@@ -141,40 +140,93 @@ export default {
       };
       luckysheet.create(options);
     },
+    // async saveData() {
+    //   // 获取当前表格的数据
+    //   const data = luckysheet.getAllSheets()[0].data; // 目前只需处理第一个工作表的数据
+    //   const formattedData = [];
+    //   // 获取表头 (假设表头在第一行,行索引为0)
+    //   const headers = data[0].map((cell) => (cell && cell.v ? cell.v : "")); // 提取表头内容
+    //   // 遍历数据行,从第二行开始 (行索引为1)
+    //   for (let i = 1; i < data.length; i++) {
+    //     const row = data[i];
+    //     const rowData = {};
+    //     // 遍历每一列,并根据表头动态生成键值对
+    //     for (let j = 0; j < headers.length; j++) {
+    //       if (row[j] && (row[j].v || row[j].v == 0)) {
+    //         rowData[headers[j]] = row[j].v || 0;
+    //       }
+    //     }
+    //     // 如果行数据不为空,加入到结果数组中
+    //     if (Object.keys(rowData).length) {
+    //       formattedData.push(rowData);
+    //     }
+    //   }
+
+    //   this.sheetData = JSON.stringify(formattedData, null, 2);
+    //   await initDatabase()
+    //     .then((database) => {
+    //       // 调用 storeSetData 方法
+    //       let fileData = {
+    //         filename: format(new Date(), "yyyyMMdd-HH:mm:ss") + this.sheetName,
+    //         fileData: JSON.parse(this.sheetData),
+    //         fileOldName: this.sheetName,
+    //         fileId: new Date().getTime(),
+    //       };
+    //       storeSetData(database, "files", "fileDataArray", fileData, () => {
+    //         this.$router.push("/home/performance/customAnalysis");
+    //       });
+    //     })
+    //     .catch((error) => {
+    //       console.error("数据库初始化失败,无法继续存储数据。", error);
+    //     });
+    // },
     async saveData() {
-      // 获取当前表格的数据
-      const data = luckysheet.getAllSheets()[0].data; // 目前只需处理第一个工作表的数据
-      const formattedData = [];
-      // 获取表头 (假设表头在第一行,行索引为0)
-      const headers = data[0].map((cell) => (cell && cell.v ? cell.v : "")); // 提取表头内容
-      // 遍历数据行,从第二行开始 (行索引为1)
-      for (let i = 1; i < data.length; i++) {
-        const row = data[i];
-        const rowData = {};
-        // 遍历每一列,并根据表头动态生成键值对
-        for (let j = 0; j < headers.length; j++) {
-          if (row[j] && (row[j].v || row[j].v == 0)) {
-            rowData[headers[j]] = row[j].v || 0;
+      // 获取所有工作表
+      const sheets = luckysheet.getAllSheets();
+      const allFileData = [];
+      sheets.forEach((sheet, ind) => {
+        const data = sheet.data; // 获取当前工作表的数据
+        const formattedData = [];
+        const headers = data[0].map((cell) => (cell && cell.v ? cell.v : "")); // 表头内容
+
+        // 遍历数据行,从第二行开始
+        for (let i = 1; i < data.length; i++) {
+          const row = data[i];
+          const rowData = {};
+          // 遍历每一列,并根据表头动态生成键值对
+          for (let j = 0; j < headers.length; j++) {
+            if (row[j] && (row[j].v || row[j].v === 0)) {
+              rowData[headers[j]] = row[j].v || 0;
+            }
+          }
+          // 如果行数据不为空,加入到结果数组中
+          if (Object.keys(rowData).length) {
+            formattedData.push(rowData);
           }
         }
-        // 如果行数据不为空,加入到结果数组中
-        if (Object.keys(rowData).length) {
-          formattedData.push(rowData);
-        }
-      }
-      this.sheetData = JSON.stringify(formattedData, null, 2);
+
+        // 生成唯一的 fileData
+        const fileData = {
+          filename:
+            format(new Date(), "yyyyMMdd-HH:mm:ss") + "_" + ind + sheet.name,
+          fileData: formattedData,
+          fileOldName: sheet.name + "_" + ind,
+          fileId: new Date().getTime() + "_" + ind,
+        };
+
+        allFileData.push(fileData); // 将当前工作表的文件数据加入到数组中
+      });
+
+      // 批量存储到数据库
       await initDatabase()
         .then((database) => {
-          // 调用 storeSetData 方法
-          let fileData = {
-            filename: format(new Date(), "yyyyMMdd-HH:mm:ss") + this.sheetName,
-            fileData: JSON.parse(this.sheetData),
-            fileOldName: this.sheetName,
-            fileId: new Date().getTime(),
-          };
-          storeSetData(database, "files", "fileDataArray", fileData, () => {
-            this.$router.push("/home/performance/customAnalysis");
+          allFileData.forEach((fileData) => {
+            storeSetData(database, "files", "fileDataArray", fileData, () => {
+              console.log("数据存储成功:", fileData.filename);
+            });
           });
+          // 跳转到分析页面
+          this.$router.push("/home/performance/customAnalysis");
         })
         .catch((error) => {
           console.error("数据库初始化失败,无法继续存储数据。", error);

+ 22 - 10
src/views/performance/customAnalysis.vue

@@ -15,7 +15,7 @@
                 action=""
                 class="upload-demo"
                 :http-request="customUpload"
-                :on-change="handleChange"
+                :on-change="validateAndHandleChange"
                 :before-upload="checkFileType"
                 :show-file-list="false"
               >
@@ -24,7 +24,7 @@
                     icon-class="table(2)"
                     style="width: 40px; height: 40px; margin-right: 10px"
                   />
-                  <span>导入CSV/EXCRL文件</span>
+                  <span>导入CSV/EXCEL文件</span>
                 </div>
               </el-upload>
             </div>
@@ -394,8 +394,10 @@ export default {
       try {
         const res = await axios.post("/sAlgorithm/CalculateFeatures/", {
           data: regionData,
-          start_index: Number(this.ruleForm.min),
-          end_index: Number(this.ruleForm.max),
+          start_index:
+            this.ruleForm.min !== null ? Number(this.ruleForm.min) : null,
+          end_index:
+            this.ruleForm.max !== null ? Number(this.ruleForm.max) : null,
         });
         return JSON.parse(res.data, "res");
       } catch (error) {
@@ -507,8 +509,16 @@ export default {
       formData.append("file", file);
       // 使用 axios 自定义上传逻辑
     },
+    // 验证并处理文件变化
+    validateAndHandleChange(file) {
+      if (this.checkFileType(file)) {
+        this.handleChange(file); // 仅当验证通过时调用 handleChange
+      }
+    },
     // 文件变化时的处理
     handleChange(file) {
+      this.checkFileType(file);
+      //csv 本身不支持多个sheet 页 ,所有以这里不需要循环处理
       if (file && file.name.endsWith(".csv")) {
         Papa.parse(file.raw, {
           header: true,
@@ -535,15 +545,16 @@ export default {
         reader.onload = (e) => {
           const data = new Uint8Array(e.target.result);
           const workbook = XLSX.read(data, { type: "array" });
-          workbook.SheetNames.forEach((sheetName) => {
+          workbook.SheetNames.forEach((sheetName, ind) => {
             const sheetData = XLSX.utils.sheet_to_json(
               workbook.Sheets[sheetName]
             );
             const fileData = {
-              filename: format(new Date(), "yyyyMMdd-HH:mm:ss") + file.name,
+              filename:
+                format(new Date(), "yyyyMMdd-HH:mm:ss") + "_" + ind + file.name,
               fileData: sheetData,
-              fileOldName: file.name,
-              fileId: new Date().getTime(),
+              fileOldName: file.name + "_" + ind,
+              fileId: new Date().getTime() + "" + "_" + ind,
             };
             if (sheetData.length > 0) {
               this.storeData(fileData);
@@ -563,9 +574,10 @@ export default {
         file.name.endsWith(".csv") ||
         file.type ===
           "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ||
-        file.name.endsWith(".xlsx");
+        file.name.endsWith(".xlsx") ||
+        file.name.endsWith(".xls");
       if (!isPdf) {
-        this.$message.error("只能上传csv文件或xlsx文件");
+        this.$message.error("只能上传csv文件或xlsx或xls文件");
         return false;
       }
       // 判断文件大小(以字节为单位,100kB = 102400字节)

+ 5 - 10
vue.config.js

@@ -72,18 +72,14 @@ module.exports = {
         pathRewrite: {
           "^/api": "", // 去掉 /api 前缀
         },
-        // onProxyReq(proxyReq, req, res) {
-        //   console.log("Proxying /api request to:", proxyReq.path); // 打印代理请求路径
-        // },
       },
-      // 未知量
+      // 未知量  //振动、激光测距仪
       "/WZLapi": {
         target: "http://192.168.50.241:9001", // WZLapi 目标地址
         changeOrigin: true,
         pathRewrite: {
           "^/WZLapi": "", // 去掉 /WZLapi 前缀
         },
-      
       },
          // 文佳
          "/WJapi": {
@@ -97,6 +93,7 @@ module.exports = {
             console.log("Proxying /sAlgorithm request to:", proxyReq.path); // 打印代理请求路径
           },
         },
+      },
       "/transDataWeb": {
         target: "http://192.168.50.241:9000/trans_data_web",
         changeOrigin: true,
@@ -105,19 +102,17 @@ module.exports = {
         },
       },
 
+      //自定义算法
       "/sAlgorithm": {
         target: "http://192.168.5.28:8666", // 目标地址
         changeOrigin: true,
         pathRewrite: {
           "^/sAlgorithm": "", // 如果后端需要 `/api` 前缀
         },
-        onProxyReq(proxyReq, req, res) {
-          console.log("Proxying /sAlgorithm request to:", proxyReq.path); // 打印代理请求路径
-        },
       },
-
+      //nodejs 数据库数据
       "/databaseApi": {
-        target: "http://192.168.5.18:3000",
+        target: "http://192.168.50.234:3000",
         changeOrigin: true,
         pathRewrite: {
           "^/databaseApi": "", // 去掉 /databaseApi 前缀