Forráskód Böngészése

生成报告代码,

liujiejie 6 hónapja
szülő
commit
17c88206d4
39 módosított fájl, 1684 hozzáadás és 477 törlés
  1. 9 2
      downLoadServer/package.json
  2. BIN
      downLoadServer/src/public/file/副本XXX风电场可靠性和能效双提升数据分析报告(模板).docx
  3. BIN
      downLoadServer/src/public/file/文字文稿1.docx
  4. 42 0
      downLoadServer/src/public/js/echarts.min.js
  5. 156 7
      downLoadServer/src/server/controllers/chartController.js
  6. 12 1
      downLoadServer/src/server/routes/chartRoutes.js
  7. 1 1
      downLoadServer/src/server/server.js
  8. 2 3
      downLoadServer/src/server/utils/chartsCom/3DDrawingChart.js
  9. 1 0
      downLoadServer/src/server/utils/chartsCom/BarChart.js
  10. 2 1
      downLoadServer/src/server/utils/chartsCom/BoxLineCharts.js
  11. 13 2
      downLoadServer/src/server/utils/chartsCom/BoxMarkersCharts.js
  12. 2 1
      downLoadServer/src/server/utils/chartsCom/ColorbarInitTwoDmarkersChart.js
  13. 164 8
      downLoadServer/src/server/utils/chartsCom/FaultAll.js
  14. 181 8
      downLoadServer/src/server/utils/chartsCom/FaultUnit.js
  15. 2 1
      downLoadServer/src/server/utils/chartsCom/GeneratorTemperature.js
  16. 2 1
      downLoadServer/src/server/utils/chartsCom/HeatmapCharts.js
  17. 18 1
      downLoadServer/src/server/utils/chartsCom/PlotlyCharts.js
  18. 156 218
      downLoadServer/src/server/utils/chartsCom/Radar.js
  19. 3 2
      downLoadServer/src/server/utils/chartsCom/Time3DChart.js
  20. 1 0
      downLoadServer/src/server/utils/chartsCom/TwoDMarkersChart.js
  21. 1 0
      downLoadServer/src/server/utils/chartsCom/TwoDMarkersChart1.js
  22. 14 1
      downLoadServer/src/server/utils/chartsCom/WindRoseChart.js
  23. 181 8
      downLoadServer/src/server/utils/chartsCom/YewErrorBarChart.js
  24. 1 0
      downLoadServer/src/server/utils/chartsCom/lineAndChildLine.js
  25. 2 2
      downLoadServer/src/server/utils/chartsCom/lineChartsFen.js
  26. 2 2
      downLoadServer/src/server/utils/chartsCom/powerMarkers2DCharts.js
  27. 49 0
      downLoadServer/src/server/utils/chartsCom/productionIndicatorTotal.js
  28. 166 8
      downLoadServer/src/server/utils/chartsCom/yawErrorBarSum.js
  29. 14 2
      downLoadServer/src/server/utils/chartsCom/yawErrorLine.js
  30. 168 0
      downLoadServer/src/server/utils/copyFileCsv.js
  31. 10 9
      src/views/overview/components/fault_all/index.vue
  32. 242 46
      src/views/performance/assetssMag.vue
  33. 7 2
      src/views/performance/components/PlotlyCharts.vue
  34. 1 115
      src/views/performance/components/chartsCom/FaultAll.vue
  35. 0 8
      src/views/performance/components/chartsCom/FaultUnit.vue
  36. 0 2
      src/views/performance/components/chartsCom/HeatmapCharts.vue
  37. 1 1
      src/views/performance/components/chartsCom/yawErrorBarSum.vue
  38. 58 14
      src/views/performance/js/allAnalysisType.js
  39. BIN
      归档.zip

+ 9 - 2
downLoadServer/package.json

@@ -12,15 +12,22 @@
   "author": "",
   "license": "ISC",
   "dependencies": {
-    "axios": "^1.6.8",
+    "axios": "^1.9.0",
     "cors": "^2.8.5",
+    "docx": "^9.5.0",
+    "docxtemplater": "^3.62.2",
+    "docxtemplater-image-module-free": "^1.1.1",
     "dotenv": "^16.5.0",
+    "echarts": "^5.6.0",
     "express": "^4.19.1",
     "form-data": "^4.0.2",
-    "fs-extra": "^11.2.0",
+    "fs-extra": "^11.3.0",
+    "image-size": "^2.0.2",
     "minio": "^8.0.5",
     "multer": "^1.4.5-lts.2",
     "node-plotly.js": "^0.0.1",
+    "papaparse": "^5.5.2",
+    "pizzip": "^3.2.0",
     "plotly.js": "^3.0.1",
     "plotly.js-dist": "^2.34.0",
     "plotly.js-dist-min": "^2.34.0",

BIN
downLoadServer/src/public/file/副本XXX风电场可靠性和能效双提升数据分析报告(模板).docx


BIN
downLoadServer/src/public/file/文字文稿1.docx


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 42 - 0
downLoadServer/src/public/js/echarts.min.js


+ 156 - 7
downLoadServer/src/server/controllers/chartController.js

@@ -16,7 +16,13 @@ import { generateGeneratorTemperature } from "../utils/chartsCom/GeneratorTemper
 import { getWindRoseChart } from "../utils/chartsCom/WindRoseChart.js";
 import { generateYawErrorLine } from "../utils/chartsCom/yawErrorLine.js";
 import { getFaultAllCharts } from "../utils/chartsCom/FaultAll.js";
+import { getFaultUnitCharts } from "../utils/chartsCom/FaultUnit.js";
+import { getYawErrorBarSumCharts } from "../utils/chartsCom/yawErrorBarSum.js";
+import { getYewErrorBarChart } from "../utils/chartsCom/YewErrorBarChart.js";
+// import { getProductionIndicatorTotal } from "../utils/chartsCom/productionIndicatorTotal.js";
+import { copyFileDocx } from "../utils/copyFileCsv.js";
 import axios from "axios";
+import Papa from "papaparse";
 
 // 提取公共逻辑到辅助函数
 const handleChartGeneration = async (
@@ -27,7 +33,8 @@ const handleChartGeneration = async (
   additionalParams = {}
 ) => {
   try {
-    const { fileAddr, bucketName, objectName } = req.body;
+    const { fileAddr, bucketName, objectName, fieldInfo, fieldEngineCode } =
+      req.body;
     if (!fileAddr) {
       return errorResponse(res, "缺少数据URL", 400);
     }
@@ -65,13 +72,15 @@ const handleChartGeneration = async (
       data,
       bucketName,
       objectName,
+      fieldEngineCode,
+      fieldInfo,
       ...Object.values(additionalParams)
     );
-
+    console.log(imageUrl, "imageUrl");
     successResponse(
       res,
       {
-        imageUrl: imageUrl,
+        imageUrl,
       },
       successMessage
     );
@@ -92,6 +101,98 @@ const handleChartGeneration = async (
     }
   }
 };
+/**
+ * 下载并解析 CSV 数据(Node.js 版)
+ * @param {string} url - CSV 地址
+ * @param {function} onParsed - 解析成功回调,返回解析后的数据
+ * @param {function} onError - 出错时的回调
+ */
+const fetchCsvAndParse = async (
+  req,
+  res,
+  onParsed,
+  onError,
+  successMessage,
+  additionalParams = {}
+) => {
+  try {
+    const { fileAddr, bucketName, objectName, fieldInfo, chartType } = req.body;
+    if (!fileAddr) {
+      return errorResponse(res, "缺少数据URL", 400);
+    }
+
+    const response = await axios.get(fileAddr, { responseType: "text" });
+    const csvText = response.data;
+    console.log(req.body, "req.body");
+    Papa.parse(csvText, {
+      header: true,
+      complete: async (result) => {
+        const data = result.data
+          .filter((row) => Object.keys(row).length)
+          .slice(0, result.data.length - 1);
+        console.log(data, "csv data 数据");
+        // 调用 onParsed 函数并确保只发送一次响应
+        try {
+          let imageUrl = "";
+          let imageUrls = [];
+          if (typeof onParsed === "function") {
+            if (chartType === "radar") {
+              const results = await Promise.all(
+                data &&
+                  data.map((val) =>
+                    onParsed(
+                      val,
+                      data,
+                      bucketName,
+                      objectName,
+                      fieldInfo,
+                      additionalParams
+                    ).catch((err) => {
+                      console.error("getRadarCharts failed:", err);
+                      return null;
+                    })
+                  )
+              );
+              imageUrls.push(...results); // 如果你还需要存入 imageUrls
+              console.log(imageUrls, "img");
+            } else {
+              imageUrl = await onParsed(
+                data,
+                bucketName,
+                objectName,
+                fieldInfo,
+                additionalParams
+              );
+            }
+          }
+          successResponse(res, { data, imageUrl, imageUrls }, successMessage);
+        } catch (error) {
+          console.error("处理解析数据时出错:", error);
+          errorResponse(res, "处理数据失败", 500);
+        }
+      },
+      error: (error) => {
+        console.error("CSV 解析错误:", error);
+        if (onError) {
+          onError(error);
+        }
+        errorResponse(res, "CSV 解析失败", 500); // 发送错误响应
+      },
+    });
+  } catch (error) {
+    console.error("获取 CSV 错误:", error);
+
+    if (error.response) {
+      errorResponse(
+        res,
+        `获取数据失败: ${error.response.status}`,
+        error.response.status
+      );
+    } else {
+      errorResponse(res, "获取 CSV 失败", 500);
+    }
+  }
+};
 
 export const createBarChart = async (req, res) => {
   await handleChartGeneration(req, res, generateBarChart, "柱状图生成成功");
@@ -154,9 +255,7 @@ export const createpowerMarkers2DCharts = async (req, res) => {
     "2D 分图生成成功"
   );
 };
-export const createRadarCharts = async (req, res) => {
-  await handleChartGeneration(req, res, getRadarCharts, "雷达图生成成功");
-};
+
 export const createBoxLineCharts = async (req, res) => {
   await handleChartGeneration(req, res, generateBoxLineChart, "箱线图生成成功");
 };
@@ -187,5 +286,55 @@ export const createYawErrorLine = async (req, res) => {
 };
 
 export const createFaultAllCharts = async (req, res) => {
-  await handleChartGeneration(req, res, getFaultAllCharts, "全场故障");
+  await fetchCsvAndParse(req, res, getFaultAllCharts, "全场故障");
+};
+//getFaultUnitCharts
+export const createFaultUnitCharts = async (req, res) => {
+  await fetchCsvAndParse(req, res, getFaultUnitCharts, "机组故障");
+};
+
+export const createyawErrorCharts = async (req, res) => {
+  await fetchCsvAndParse(
+    req,
+    res,
+    getYawErrorBarSumCharts,
+    "静态偏航误差的绝对值机组台数分布情况"
+  );
+};
+export const createyawErrorBarSumCharts = async (req, res) => {
+  await fetchCsvAndParse(req, res, getYewErrorBarChart, "静态偏航误差值图");
+};
+//全场运行指标
+export const createProductionIndicatorTotal = async (req, res) => {
+  await fetchCsvAndParse(req, res, "", "全场运行指标");
+};
+export const createRadarCharts = async (req, res) => {
+  await fetchCsvAndParse(req, res, getRadarCharts, "雷达图生成成功");
+};
+
+export const createCopyFileCsv = async (req, res) => {
+  try {
+    // 从请求体中获取 fieldInfo
+    const { fieldInfo } = req.body;
+
+    if (!fieldInfo) {
+      return res.status(400).json({
+        success: false,
+        message: "缺少必要的 fieldInfo 参数",
+      });
+    }
+
+    const result = await copyFileDocx(fieldInfo, req.body);
+    res.json({
+      success: true,
+      message: result,
+    });
+  } catch (error) {
+    console.error("生成文档失败:", error);
+    res.status(500).json({
+      success: false,
+      message: "生成文档失败",
+      error: error.message,
+    });
+  }
 };

+ 12 - 1
downLoadServer/src/server/routes/chartRoutes.js

@@ -17,6 +17,11 @@ import {
   createGetWindRoseChart,
   createYawErrorLine,
   createFaultAllCharts,
+  createFaultUnitCharts,
+  createyawErrorCharts,
+  createyawErrorBarSumCharts,
+  createProductionIndicatorTotal,
+  createCopyFileCsv,
 } from "../controllers/chartController.js";
 
 const router = express.Router();
@@ -34,11 +39,17 @@ router.post(
   createColorbarInitTwoDmarkersChart
 );
 router.post("/powerMarkers2DCharts", createpowerMarkers2DCharts);
-router.post("/radarChart", createRadarCharts);
+
 router.post("/boxLineCharts", createBoxLineCharts);
 router.post("/boxMarkersCharts", createBoxMarkersCharts);
 router.post("/generatorTemperature", createGeneratorTemperature);
 router.post("/windRoseChart", createGetWindRoseChart);
 router.post("/yawErrorLine", createYawErrorLine);
 router.post("/faultAllChart", createFaultAllCharts);
+router.post("/faultUnitChart", createFaultUnitCharts);
+router.post("/yawErrorChart", createyawErrorCharts);
+router.post("/yawErrorBarSumChart", createyawErrorBarSumCharts);
+router.post("/productionIndicatorTotal", createProductionIndicatorTotal);
+router.post("/radarChart", createRadarCharts);
+router.post("/CopyFileCsv", createCopyFileCsv);
 export default router;

+ 1 - 1
downLoadServer/src/server/server.js

@@ -17,7 +17,7 @@ const app = express();
 // 使用 cors 中间件
 app.use(cors());
 // 中间件
-app.use(express.json());
+app.use(express.json({ limit: "100mb" }));
 app.use(logger);
 
 // 静态文件服务

+ 2 - 3
downLoadServer/src/server/utils/chartsCom/3DDrawingChart.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-04-14 16:09:13
- * @LastEditTime: 2025-05-14 16:12:44
+ * @LastEditTime: 2025-05-21 15:09:29
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /downLoadServer/src/server/utils/chartsCom/3DDrawingChart.js
@@ -24,7 +24,6 @@ export const generate3DDrawingChart = async (data, bucketName, objectName) => {
       tempDir,
       `temp_heatmap_chart_${Date.now()}.png`
     );
-
     // 获取 plotly.js 的绝对路径
     const plotlyPath = path.join(
       process.cwd(),
@@ -211,7 +210,7 @@ export const generate3DDrawingChart = async (data, bucketName, objectName) => {
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
-      return formData;
+      return response?.data?.url;
     } catch (error) {
       console.error("生成3D图失败:", error);
       throw error;

+ 1 - 0
downLoadServer/src/server/utils/chartsCom/BarChart.js

@@ -206,6 +206,7 @@ export const generateBarChart = async (data, bucketName, objectName) => {
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } finally {
       await browser.close();
     }

+ 2 - 1
downLoadServer/src/server/utils/chartsCom/BoxLineCharts.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-05-12 17:40:10
- * @LastEditTime: 2025-05-13 10:46:19
+ * @LastEditTime: 2025-05-21 15:09:53
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /downLoadServer/src/server/utils/chartsCom/BoxLineCharts.js
@@ -168,6 +168,7 @@ export const generateBoxLineChart = async (data, bucketName, objectName) => {
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } finally {
       await browser.close();
     }

+ 13 - 2
downLoadServer/src/server/utils/chartsCom/BoxMarkersCharts.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-05-13 11:02:32
- * @LastEditTime: 2025-05-13 14:26:23
+ * @LastEditTime: 2025-05-21 15:10:00
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /downLoadServer/src/server/utils/chartsCom/BoxMarkersCharts.js
@@ -66,6 +66,15 @@ export const generateBoxMarkersCharts = async (
 
   const traces = [];
   const medianMarkers = [];
+  // 获取 plotly.js 的绝对路径
+  const plotlyPath = path.join(
+    process.cwd(),
+    "src",
+    "public",
+    "js",
+    "plotly-3.0.1.min.js"
+  );
+  const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
 
   filteredData.forEach((group) => {
     traces.push({
@@ -137,7 +146,8 @@ export const generateBoxMarkersCharts = async (
         <!DOCTYPE html>
         <html>
           <head>
-            <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+           <meta charset="UTF-8">
+           <script>${plotlyContent}</script>
             <style>
               body { margin: 0; }
               #chart { width: 800px; height: 600px; }
@@ -185,6 +195,7 @@ export const generateBoxMarkersCharts = async (
     );
 
     console.log("上传成功:", response.data);
+    return response?.data?.url;
   } finally {
     await browser.close();
   }

+ 2 - 1
downLoadServer/src/server/utils/chartsCom/ColorbarInitTwoDmarkersChart.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-04-28 10:27:00
- * @LastEditTime: 2025-05-08 15:24:44
+ * @LastEditTime: 2025-05-23 15:32:06
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /downLoadServer/src/server/utils/chartsCom/ColorbarInitTwoDmarkersChart.js
@@ -208,6 +208,7 @@ export const generateColorbarInitTwoDmarkersChart = async (
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } catch (error) {
       console.error("生成2D散点图失败:", error);
       throw error;

+ 164 - 8
downLoadServer/src/server/utils/chartsCom/FaultAll.js

@@ -1,24 +1,180 @@
-/*
- * @Author: your name
- * @Date: 2025-05-15 15:20:13
- * @LastEditTime: 2025-05-15 15:24:24
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /downLoadServer/src/server/utils/chartsCom/FaultAll.js
- */
 import puppeteer from "puppeteer";
 import fs from "fs-extra";
 import path from "path";
 import FormData from "form-data";
 import axios from "axios"; // 导入 axios
 import { colorSchemes } from "../colors.js";
+
 export const getFaultAllCharts = async (
   data,
   bucketName,
   objectName,
   analysisTypeCode
 ) => {
+  // 获取 plotly.js 的绝对路径
+  const plotlyPath = path.join(
+    process.cwd(),
+    "src",
+    "public",
+    "js",
+    "plotly-3.0.1.min.js"
+  );
+  const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
+  console.log(data, "全场故障数据");
   try {
+    // 提取故障类型、故障次数和故障时长
+    const faultTypes = data.map((item) => item.fault_detail);
+    const faultCounts = data.map((item) => item.count);
+    const faultDurations = data.map((item) => item.fault_time_sum);
+
+    // 故障次数的柱状图数据(左侧 Y 轴)
+    const barTrace = {
+      x: faultTypes.slice(0, 10),
+      y: faultCounts.slice(0, 10),
+      type: "bar",
+      marker: { color: "#64ADC2" }, // 蓝色柱状图
+      name: "故障次数",
+      hovertemplate: `故障类型: %{x} <br> 故障次数: %{y} 次<br>`,
+    };
+
+    // 故障时长的折线图数据(右侧 Y 轴)
+    const lineTrace = {
+      x: faultTypes.slice(0, 10),
+      y: faultDurations.slice(0, 10),
+      type: "scatter",
+      mode: "lines+markers", // 线性图 + 点标记
+      line: { color: "#1A295D" }, // 红色折线
+      name: "故障时长",
+      yaxis: "y2", // 使用第二个 Y 轴(右侧)
+      hovertemplate: `故障类型: %{x} <br> 故障时长: %{y} 分钟 <br>`,
+    };
+
+    // 布局配置,设置双 Y 轴
+    const layout = {
+      title: {
+        text: "全场故障次数与时长分析Top10",
+        font: {
+          size: 16, // 设置标题字体大小(默认 16)
+          weight: "bold",
+        },
+      },
+      xaxis: {
+        title: {
+          text: "故障类型",
+        },
+
+        tickangle: 30,
+        tickmode: "array",
+        tickvals: faultTypes.slice(0, 10),
+        tickfont: { size: 12 },
+        gridcolor: "rgb(255,255,255)",
+        tickcolor: "rgb(255,255,255)",
+        backgroundcolor: "#e5ecf6",
+      },
+      yaxis: {
+        title: {
+          text: "故障次数",
+        },
+        titlefont: { color: "#64ADC2" },
+        tickfont: { color: "#64ADC2" },
+        side: "left", // 左侧的 Y 轴
+        showline: true,
+        linecolor: "#64ADC2",
+        gridcolor: "rgb(255,255,255)",
+        tickcolor: "rgb(255,255,255)",
+        backgroundcolor: "#e5ecf6",
+      },
+      yaxis2: {
+        title: {
+          text: "故障时长 (分钟)",
+        },
+        titlefont: { color: "#1A295D" },
+        tickfont: { color: "#1A295D" },
+        overlaying: "y", // 在第一个 Y 轴上方绘制
+        side: "right", // 右侧的 Y 轴
+        position: 1, // 调整右侧轴的位置
+        showline: true,
+        linecolor: "#1A295D", // 设置右侧轴线颜色
+      },
+      barmode: "group", // 柱状图分组
+      plot_bgcolor: "#e5ecf6",
+      gridcolor: "#fff",
+      bgcolor: "#e5ecf6", // 设置背景颜色
+      showlegend: false,
+      margin: {
+        t: 80, // 上边距
+        b: 150, // 下边距,给 X 轴标签更多空间
+      },
+    };
+
+    // 创建临时目录
+    const tempDir = path.join(process.cwd(), "images");
+    await fs.ensureDir(tempDir);
+    const tempFilePath = path.join(
+      tempDir,
+      `temp_fault_all_chart_${Date.now()}.png`
+    );
+
+    // 使用 Puppeteer 生成图表的截图
+    const browser = await puppeteer.launch({
+      headless: "new",
+      args: ["--no-sandbox", "--disable-setuid-sandbox"],
+    });
+    try {
+      const page = await browser.newPage();
+      const htmlContent = `
+        <!DOCTYPE html>
+        <html>
+          <head>
+            <meta charset="UTF-8">
+            <title>全场故障</title>
+            <script>${plotlyContent}</script>
+            <style>
+              body { margin: 0; }
+              #chart { width: 800px; height: 600px; }
+            </style>
+          </head>
+          <body>
+            <div id="chart"></div>
+            <script>
+              window.onload = function() {
+                Plotly.newPlot('chart', [${JSON.stringify(
+                  barTrace
+                )}, ${JSON.stringify(lineTrace)}], ${JSON.stringify(
+        layout
+      )}).then(() => {
+                  window.chartRendered = true;
+                });
+              };
+            </script>
+          </body>
+        </html>
+      `;
+      await page.setContent(htmlContent, { waitUntil: "networkidle0" });
+      await page.waitForFunction(() => window.chartRendered === true, {
+        timeout: 60000,
+      });
+      // 截图并保存到临时文件
+      const chartElement = await page.$("#chart");
+      await chartElement.screenshot({ path: tempFilePath, type: "png" });
+      // 上传图片到服务器
+      const formData = new FormData();
+      formData.append("file", fs.createReadStream(tempFilePath));
+      const response = await axios.post(
+        `${process.env.API_BASE_URL}/examples/upload`,
+        {
+          filePath: tempFilePath,
+          bucketName,
+          objectName,
+        }
+      );
+      console.log("上传成功:", response.data);
+      return response?.data?.url;
+    } catch (error) {
+      console.error("生成图表失败:", error);
+    } finally {
+      await browser.close();
+    }
   } catch (error) {
     console.error("发生错误:", error);
   }

+ 181 - 8
downLoadServer/src/server/utils/chartsCom/FaultUnit.js

@@ -1,8 +1,181 @@
-/*
- * @Author: your name
- * @Date: 2025-05-15 15:20:24
- * @LastEditTime: 2025-05-15 15:20:25
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /downLoadServer/src/server/utils/chartsCom/FaultUnit.js
- */
+import puppeteer from "puppeteer";
+import fs from "fs-extra";
+import path from "path";
+import FormData from "form-data";
+import axios from "axios"; // 导入 axios
+import { colorSchemes } from "../colors.js";
+
+export const getFaultUnitCharts = async (
+  data,
+  bucketName,
+  objectName,
+  analysisTypeCode
+) => {
+  try {
+    // 获取 plotly.js 的绝对路径
+    const plotlyPath = path.join(
+      process.cwd(),
+      "src",
+      "public",
+      "js",
+      "plotly-3.0.1.min.js"
+    );
+    const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
+
+    // 提取故障机组、故障次数和故障时长
+    const faultTypes = data.map((item) => item.wind_turbine_name);
+    const faultCounts = data.map((item) => item.count);
+    const faultDurations = data.map((item) => item.fault_time);
+    console.log();
+    // 故障次数的散点图数据(左侧 Y 轴)
+    const scatterFaultCounts = {
+      x: faultTypes.slice(0, 10),
+      y: faultCounts.slice(0, 10),
+      mode: "markers", // 散点图
+      marker: { color: "#64ADC2", size: 10 }, // 蓝色散点
+      name: "故障次数",
+      hovertemplate: `机组: %{x} <br> 故障次数: %{y} 次<br>`,
+    };
+
+    // 故障时长的散点图数据(右侧 Y 轴)
+    const scatterFaultDurations = {
+      x: faultTypes.slice(0, 10),
+      y: faultDurations.slice(0, 10),
+      mode: "markers", // 散点图
+      marker: { color: "#1A295D", size: 10 }, // 红色散点
+      name: "故障时长",
+      yaxis: "y2", // 使用第二个 Y 轴(右侧)
+      hovertemplate: `机组: %{x} <br> 故障时长: %{y} 秒<br>`,
+    };
+
+    // 布局配置,设置双 Y 轴
+    const layout = {
+      title: {
+        text: "机组故障次数与时长分析Top10",
+        font: {
+          size: 16,
+          weight: "bold",
+        },
+      },
+      xaxis: {
+        title: {
+          text: "故障机组",
+        },
+        tickangle: 30,
+        tickmode: "array",
+        tickvals: faultTypes.slice(0, 10), // 保证这里是字符串数组
+        ticktext: faultTypes.slice(0, 10), // 确保 ticktext 使用相同的标签
+        tickfont: { size: 12 },
+        type: "category", // 让 Y 轴按类别均匀分布
+        gridcolor: "rgb(255,255,255)",
+        tickcolor: "rgb(255,255,255)",
+        backgroundcolor: "#e5ecf6",
+      },
+      yaxis: {
+        title: {
+          text: "故障次数",
+        },
+        titlefont: { color: "#64ADC2" },
+        tickfont: { color: "#64ADC2" },
+        side: "left", // 左侧的 Y 轴
+        showline: true,
+        linecolor: "#64ADC2",
+        gridcolor: "rgb(255,255,255)",
+        tickcolor: "rgb(255,255,255)",
+        backgroundcolor: "#e5ecf6",
+      },
+      yaxis2: {
+        title: {
+          text: "故障时长(秒)",
+        },
+        titlefont: { color: "#1A295D" },
+        tickfont: { color: "#1A295D" },
+        showgrid: false, // 隐藏 Y 轴网格线
+        overlaying: "y", // 在第一个 Y 轴上方绘制
+        side: "right", // 右侧的 Y 轴
+        position: 1, // 调整右侧轴的位置
+        showline: true,
+        linecolor: "#1A295D", // 设置右侧轴线颜色
+      },
+      plot_bgcolor: "#e5ecf6",
+      gridcolor: "#fff",
+      bgcolor: "#e5ecf6", // 设置背景颜色
+      showlegend: false, // 显示图例
+      margin: {
+        t: 80, // 上边距
+        b: 150, // 下边距,给 X 轴标签更多空间
+      },
+    };
+
+    // 创建临时目录
+    const tempDir = path.join(process.cwd(), "images");
+    await fs.ensureDir(tempDir);
+    const tempFilePath = path.join(
+      tempDir,
+      `temp_fault_unit_chart_${Date.now()}.png`
+    );
+
+    // 使用 Puppeteer 生成图表的截图
+    const browser = await puppeteer.launch({
+      headless: "new",
+      args: ["--no-sandbox", "--disable-setuid-sandbox"],
+    });
+    try {
+      const page = await browser.newPage();
+      const htmlContent = `
+        <!DOCTYPE html>
+        <html>
+          <head>
+            <meta charset="UTF-8">
+            <title>机组故障</title>
+            <script>${plotlyContent}</script>
+            <style>
+              body { margin: 0; }
+              #chart { width: 800px; height: 600px; }
+            </style>
+          </head>
+          <body>
+            <div id="chart"></div>
+            <script>
+              window.onload = function() {
+                Plotly.newPlot('chart', [${JSON.stringify(
+                  scatterFaultCounts
+                )}, ${JSON.stringify(scatterFaultDurations)}], ${JSON.stringify(
+        layout
+      )}).then(() => {
+                  window.chartRendered = true;
+                });
+              };
+            </script>
+          </body>
+        </html>
+      `;
+      await page.setContent(htmlContent, { waitUntil: "networkidle0" });
+      await page.waitForFunction(() => window.chartRendered === true, {
+        timeout: 60000,
+      });
+      // 截图并保存到临时文件
+      const chartElement = await page.$("#chart");
+      await chartElement.screenshot({ path: tempFilePath, type: "png" });
+      // 上传图片到服务器
+      const formData = new FormData();
+      formData.append("file", fs.createReadStream(tempFilePath));
+      const response = await axios.post(
+        `${process.env.API_BASE_URL}/examples/upload`,
+        {
+          filePath: tempFilePath,
+          bucketName,
+          objectName,
+        }
+      );
+      // console.log("上传成功:", response.data);
+      return response?.data?.url;
+    } catch (error) {
+      console.error("生成图表失败:", error);
+    } finally {
+      await browser.close();
+    }
+  } catch (error) {
+    console.error("发生错误:", error);
+  }
+};

+ 2 - 1
downLoadServer/src/server/utils/chartsCom/GeneratorTemperature.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-05-13 14:33:50
- * @LastEditTime: 2025-05-13 15:06:37
+ * @LastEditTime: 2025-05-21 15:10:12
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /downLoadServer/src/server/utils/chartsCom/GeneratorTemperature.js
@@ -172,6 +172,7 @@ export const generateGeneratorTemperature = async (
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } finally {
       await browser.close();
     }

+ 2 - 1
downLoadServer/src/server/utils/chartsCom/HeatmapCharts.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-04-14 11:15:35
- * @LastEditTime: 2025-05-08 15:25:27
+ * @LastEditTime: 2025-05-21 15:10:19
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/downLoadServer/src/server/utils/chartsCom/HeatmapCharts.js
@@ -166,6 +166,7 @@ export const generateHeatmapChart = async (data, bucketName, objectName) => {
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } catch (error) {
       console.error("生成热力图失败:", error);
       throw error;

+ 18 - 1
downLoadServer/src/server/utils/chartsCom/PlotlyCharts.js

@@ -1,8 +1,25 @@
 /*
  * @Author: your name
  * @Date: 2025-05-15 15:22:19
- * @LastEditTime: 2025-05-15 15:22:20
+ * @LastEditTime: 2025-05-16 11:10:47
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /downLoadServer/src/server/utils/chartsCom/PlotlyCharts.js
  */
+import puppeteer from "puppeteer";
+import fs from "fs-extra";
+import path from "path";
+import FormData from "form-data";
+import axios from "axios"; // 导入 axios
+import { colorSchemes } from "../colors.js";
+export const getPlotlyCharts = async (
+  data,
+  bucketName,
+  objectName,
+  analysisTypeCode
+) => {
+  try {
+  } catch (error) {
+    console.error("发生错误:", error);
+  }
+};

+ 156 - 218
downLoadServer/src/server/utils/chartsCom/Radar.js

@@ -3,230 +3,168 @@ import fs from "fs-extra";
 import path from "path";
 import FormData from "form-data";
 import { colorSchemes } from "../colors.js";
-import axios from "axios"; // 导入 axios
-
-export const getRadarCharts = async (data, bucketName, objectName) => {
-  try {
-    const colorsBar = colorSchemes[0].colors;
-    // 创建临时目录
-    const tempDir = path.join(process.cwd(), "images");
-    await fs.ensureDir(tempDir);
-    const tempFilePath = path.join(
-      tempDir,
-      `temp_scatter_chart_${Date.now()}.png`
-    );
-
-    // 获取 plotly.js 的绝对路径
-    const plotlyPath = path.join(
-      process.cwd(),
-      "src",
-      "public",
-      "js",
-      "plotly-3.0.1.min.js"
-    );
-    const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
-
-    // 创建浏览器实例
-    const browser = await puppeteer.launch({
-      headless: "new",
-      args: ["--no-sandbox", "--disable-setuid-sandbox"],
-    });
-
-    try {
-      // 计算最大值、最小值和中位值
-      const values = calculateValues(data);
-      const chartData = drawRadarChart(values);
-
-      // 使用 Puppeteer 生成图表的截图
-      const page = await browser.newPage();
-      const htmlContent = `
-        <!DOCTYPE html>
-        <html>
-          <head>
-            <script>${plotlyContent}</script>
-            <style>
-              body { margin: 0; }
-              #chart { width: 800px; height: 600px; }
-            </style>
-          </head>
-          <body>
-            <div id="chart"></div>
-            <script>
-              window.onload = function() {
-                const traces = ${JSON.stringify(chartData.traces)};
-                const layout = ${JSON.stringify(chartData.layout)};
-                Plotly.newPlot('chart', traces, layout).then(() => {
-                  window.chartRendered = true;
-                });
-              };
-            </script>
-          </body>
-        </html>
-      `;
-
-      await page.setContent(htmlContent, { waitUntil: "networkidle0" });
-      await page.waitForFunction(() => window.chartRendered === true, {
-        timeout: 60000,
+import axios from "axios";
+// 获取 plotly.js 的绝对路径
+const plotlyPath = path.join(
+  process.cwd(),
+  "src",
+  "public",
+  "js",
+  "echarts.min.js"
+);
+const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
+
+// HTML 模板
+const getHtmlContent = () => `
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Radar Chart</title>
+  <script>${plotlyContent}</script>
+  <style>
+    html, body { margin: 0; padding: 0; width: 600px; height: 600px; }
+    #chart { width: 100%; height: 100%; }
+  </style>
+</head>
+<body>
+  <div id="chart"></div>
+  <script>
+    window.renderChart = function (chartData, itemCsvData) {
+      function calcValues(data) {
+        const matrix = data.map((item) => [
+          item.TurbinePowerRate,
+          item.TurbineRunRate,
+          item.WindSpeedAvr,
+          item.Thi,
+          item.Ws,
+        ]);
+        const max = matrix[0].map((_, i) => Math.max(...matrix.map(row => row[i])));
+        const min = matrix[0].map((_, i) => Math.min(...matrix.map(row => row[i])));
+        const median = matrix[0].map((_, i) => {
+          const sorted = matrix.map(row => row[i]).sort((a, b) => a - b);
+          const mid = Math.floor(sorted.length / 2);
+          return sorted.length % 2 === 0
+            ? (sorted[mid - 1] + sorted[mid]) / 2
+            : sorted[mid];
+        });
+        return { max, min, median };
+      }
+
+      const { max, min, median } = calcValues(itemCsvData);
+      const values = [
+        chartData.TurbinePowerRate,
+        chartData.TurbineRunRate,
+        chartData.WindSpeedAvr,
+        chartData.Thi,
+        chartData.Ws,
+      ];
+
+      const indicators = [
+        { name: "风机能量利用率", max: max[0], min: min[0] },
+        { name: "风机可利用率", max: max[1], min: min[1] },
+        { name: "平均风速", max: max[2], min: min[2] },
+        { name: "等效利用小时", max: max[3], min: min[3] },
+        { name: "功率曲线一致性系数", max: max[4], min: min[4] },
+      ];
+
+      const chart = echarts.init(document.getElementById("chart"));
+      chart.setOption({
+        title: {
+          text: chartData.wind_turbine_name + "机组指标",
+          left: "center",
+        },
+        radar: {
+          indicator: indicators,
+          center: ["50%", "50%"],
+          radius: "60%",
+        },
+        series: [
+          {
+            type: "radar",
+            data: [
+              {
+                value: values,
+                name: chartData.wind_turbine_name,
+                areaStyle: { color: "rgba(99,110,252,0.3)" },
+              },
+              {
+                value: median,
+                name: "中位值",
+                lineStyle: {
+                  type: "dashed",
+                  color: "#f39c12",
+                },
+              },
+            ],
+          },
+        ],
       });
-
-      // 截图并保存到临时文件
-      const chartElement = await page.$("#chart");
-      await chartElement.screenshot({ path: tempFilePath, type: "png" });
-
-      // 上传图片到服务器
-      const formData = new FormData();
-      formData.append("file", fs.createReadStream(tempFilePath));
-      const response = await axios.post(
-        `${process.env.API_BASE_URL}/examples/upload`,
-        {
-          filePath: tempFilePath,
-          bucketName,
-          objectName,
-        }
-      );
-
-      console.log("上传成功:", response.data);
-    } catch (error) {
-      console.error("绘制雷达图失败:", error);
-    } finally {
-      await browser.close();
-    }
-  } catch (error) {
-    console.error("发生错误:", error);
-  }
-};
-
-// 计算最大值、最小值和中位值
-function calculateValues(data) {
-  const itemCsvData = data; // 假设 data 是传入的 CSV 数据
-  const processedData = itemCsvData.map((item) => [
-    item.TurbinePowerRate,
-    item.TurbineRunRate,
-    item.WindSpeedAvr,
-    item.Thi,
-    item.Ws,
-  ]);
-
-  // 计算最大值
-  const maxValues = processedData[0].map((_, colIndex) =>
-    Math.max(...processedData.map((row) => row[colIndex]))
+    };
+  </script>
+</body>
+</html>
+`;
+
+export const getRadarCharts = async (
+  chartData,
+  itemCsvData,
+  bucketName,
+  objectName
+) => {
+  const browser = await puppeteer.launch();
+  const page = await browser.newPage();
+  // 创建临时目录
+  const tempDir = path.join(process.cwd(), "images");
+  await fs.ensureDir(tempDir);
+  const tempFilePath = path.join(
+    tempDir,
+    `temp_scatter_chart_${Date.now()}.png`
   );
 
-  // 计算最小值
-  const minValues = processedData[0].map((_, colIndex) =>
-    Math.min(...processedData.map((row) => row[colIndex]))
-  );
+  await page.setContent(getHtmlContent(), { waitUntil: "load" });
 
-  // 计算中位值
-  const medianValues = calculateMedian(processedData);
+  // 等待 renderChart 被定义
+  await page.waitForFunction(() => typeof window.renderChart === "function");
 
-  return { maxValues, minValues, medianValues };
-}
+  // 调用渲染函数
+  await page.evaluate(
+    (chartData, itemCsvData) => {
+      window.renderChart(chartData, itemCsvData);
+    },
+    chartData,
+    itemCsvData
+  );
 
-// 计算每列的中位值
-function calculateMedian(data) {
-  return data[0].map((_, colIndex) => {
-    const columnData = data
-      .map((row) => parseFloat(row[colIndex])) // 将字符串转换为数字
-      .sort((a, b) => a - b); // 数字排序
-    const mid = Math.floor(columnData.length / 2);
-    return columnData.length % 2 === 0
-      ? (columnData[mid - 1] + columnData[mid]) / 2
-      : columnData[mid];
+  // 再等待图表渲染完成(给 ECharts 时间)
+  (await page.waitForTimeout)
+    ? page.waitForTimeout(1000)
+    : new Promise((res) => setTimeout(res, 1000));
+
+  // 上传逻辑
+  // 截图并保存到临时文件
+  const chartElement = await page.$("#chart");
+  await chartElement.screenshot({
+    path: tempFilePath,
+    type: "png",
   });
-}
 
-// 渲染雷达图
-function drawRadarChart({ maxValues, minValues, medianValues }) {
-  // 获取数据
-  const values = [
-    // 这里需要根据实际数据填充
-  ];
-
-  // 雷达图的指示器,使用最大值、最小值和中位值来动态设置
-  const indicators = [
-    {
-      name: "风机能量利用率",
-      max: maxValues[0],
-      min: minValues[0],
-    },
-    {
-      name: "风机可利用率",
-      max: maxValues[1],
-      min: minValues[1],
-    },
-    { name: "平均风速", max: maxValues[2], min: minValues[2] },
-    {
-      name: "等效利用小时",
-      max: maxValues[3],
-      min: minValues[3],
-    },
-    {
-      name: "功率曲线一致性系数",
-      max: maxValues[4],
-      min: minValues[4],
-    },
-  ];
-
-  // 构建 ECharts 配置项
-  const option = {
-    title: {
-      text: "机组指标",
-      left: "center",
-      textStyle: {
-        fontSize: 16,
-      },
-    },
-    tooltip: {
-      trigger: "item",
-      formatter: (params) => {
-        const indicators = [
-          { label: "风机能量利用率", unit: " %" },
-          { label: "风机可利用率", unit: " %" },
-          { label: "平均风速", unit: " m/s" },
-          { label: "利用小时", unit: " h" },
-          { label: "功率曲线一致性系数", unit: " %" },
-        ];
-        const values = params.value;
-        let content = `<strong>${params.seriesName}</strong><br/>`;
-        for (let i = 0; i < indicators.length; i++) {
-          content += `${indicators[i].label}: ${values[i]}${
-            indicators[i].unit
-          }<br/>中位值: ${parseFloat(medianValues[i].toFixed(3))}${
-            indicators[i].unit
-          }<br/><br/>`;
-        }
-        return content;
-      },
-    },
-    radar: {
-      indicator: indicators,
-      center: ["45%", "45%"],
-      radius: "50%",
-    },
-    series: [
-      {
-        name: "机组指标",
-        type: "radar",
-        data: [
-          {
-            value: values,
-            name: "机组指标",
-          },
-        ],
-      },
+  try {
+    const newUrl = objectName.substring(0, objectName.lastIndexOf("/"));
+    // 上传图片到服务器
+    const formData = new FormData();
+    formData.append("file", fs.createReadStream(tempFilePath));
+    // 发送上传请求
+    const response = await axios.post(
+      `${process.env.API_BASE_URL}/examples/upload`,
       {
-        name: "中位值",
-        type: "radar",
-        data: [
-          {
-            value: medianValues,
-            name: "中位值",
-          },
-        ],
-      },
-    ],
-  };
-
-  return { traces: option.series, layout: option }; // 返回图表数据和布局
-}
+        filePath: tempFilePath,
+        bucketName,
+        objectName: newUrl + "/" + chartData.wind_turbine_name + ".jpg",
+      }
+    );
+    return response?.data?.url;
+  } catch (error) {
+    console.error("❌ 上传失败:", error.message);
+  }
+};

+ 3 - 2
downLoadServer/src/server/utils/chartsCom/Time3DChart.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-04-14 17:49:33
- * @LastEditTime: 2025-05-14 16:00:42
+ * @LastEditTime: 2025-05-21 15:11:06
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/downLoadServer/src/server/utils/chartsCom/Time3DChart.js
@@ -179,7 +179,7 @@ export const generateTime3DChart = async (data, bucketName, objectName) => {
         <html>
         <head>
           <meta charset="UTF-8">
-          <title>热力图</title>
+          <title>3D图</title>
           <script>${plotlyContent}</script>
         </head>
         <body>
@@ -224,6 +224,7 @@ export const generateTime3DChart = async (data, bucketName, objectName) => {
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } catch (error) {
       console.error("生成3D图失败:", error);
       throw error;

+ 1 - 0
downLoadServer/src/server/utils/chartsCom/TwoDMarkersChart.js

@@ -175,6 +175,7 @@ export const generateTwoDMarkersChart = async (
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } catch (error) {
       console.error("生成2D散点图失败:", error);
       throw error;

+ 1 - 0
downLoadServer/src/server/utils/chartsCom/TwoDMarkersChart1.js

@@ -197,6 +197,7 @@ export const generateTwoDMarkersChart1 = async (
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } catch (error) {
       console.error("生成2D散点图失败:", error);
       throw error;

+ 14 - 1
downLoadServer/src/server/utils/chartsCom/WindRoseChart.js

@@ -12,6 +12,16 @@ export const getWindRoseChart = async (
   analysisTypeCode
 ) => {
   try {
+    // 获取 plotly.js 的绝对路径
+    const plotlyPath = path.join(
+      process.cwd(),
+      "src",
+      "public",
+      "js",
+      "plotly-3.0.1.min.js"
+    );
+    const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
+
     const windRoseList = data.data; // 确保数据源一致
     // 创建临时目录
     const tempDir = path.join(process.cwd(), "images");
@@ -122,7 +132,9 @@ export const getWindRoseChart = async (
         <!DOCTYPE html>
         <html>
           <head>
-            <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+            <meta charset="UTF-8">
+            <title>玫瑰图</title>
+            <script>${plotlyContent}</script>
             <style>
               body { margin: 0; }
               #chart { width: 800px; height: 600px; }
@@ -161,6 +173,7 @@ export const getWindRoseChart = async (
         }
       );
       console.log("上传成功:", response.data);
+      return response?.data?.url;
     } catch (error) {
       console.error("生成图表失败:", error);
     } finally {

+ 181 - 8
downLoadServer/src/server/utils/chartsCom/YewErrorBarChart.js

@@ -1,8 +1,181 @@
-/*
- * @Author: your name
- * @Date: 2025-05-15 15:21:44
- * @LastEditTime: 2025-05-15 15:21:45
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /downLoadServer/src/server/utils/chartsCom/YewErrorBarChart.js
- */
+import puppeteer from "puppeteer";
+import fs from "fs-extra";
+import path from "path";
+import FormData from "form-data";
+import axios from "axios"; // 导入 axios
+import { colorSchemes } from "../colors.js";
+
+export const getYewErrorBarChart = async (
+  data,
+  bucketName,
+  objectName,
+  analysisTypeCode
+) => {
+  try {
+    // 提取机组编号和偏航误差值
+    const xData = data.map((item) => item.engine_name); // 机组编号
+    const yData = data.map((item) => item.yaw_error1); // 偏航误差值
+
+    // 为每个数据点分配颜色
+    const colors = yData.map((value) => {
+      if (value <= 3) {
+        return "#8AC8BE"; // (0, 3] 蓝色
+      } else if (value <= 5) {
+        return "#407DB3"; // (3, 5] 绿色
+      } else {
+        return "#1B2973"; // (5, ∞] 红色
+      }
+    });
+
+    const trace = {
+      x: xData, // 横坐标数据
+      y: yData, // 纵坐标数据
+      type: "bar", // 当前图表类型
+      marker: {
+        color: colors, // 每个点的颜色
+      },
+      name: "偏航误差值", // 图例名称
+    };
+    // 创建虚拟的 trace 以便显示图例
+    const legendTrace1 = {
+      x: [null],
+      y: [null],
+      name: "(0, 3]",
+      mode: "markers",
+      marker: { color: "#8AC8BE", size: 10 },
+    };
+    const legendTrace2 = {
+      x: [null],
+      y: [null],
+      name: "(3, 5]",
+      mode: "markers",
+      marker: { color: "#407DB3", size: 10 },
+    };
+    const legendTrace3 = {
+      x: [null],
+      y: [null],
+      name: "(5, ∞]",
+      mode: "markers",
+      marker: { color: "#1B2973", size: 10 },
+    };
+    const layout = {
+      title: {
+        text: "机组静态偏航误差值", // 图表标题
+        font: {
+          size: 16, // 设置标题字体大小(默认 16)
+          weight: "bold",
+        },
+      },
+      xaxis: {
+        title: {
+          text: "机组编号",
+        }, // 横坐标标题
+        tickmode: "array",
+        tickvals: xData, // 设置刻度值(机组编号)
+        ticktext: xData, // 设置刻度文本(机组编号)
+        gridcolor: "rgb(255,255,255)",
+        tickcolor: "rgb(255,255,255)",
+        backgroundcolor: "#e5ecf6",
+      },
+      yaxis: {
+        title: {
+          text: "静态偏航误差值(度)",
+        }, // 纵坐标标题
+        gridcolor: "rgb(255,255,255)",
+        tickcolor: "rgb(255,255,255)",
+        backgroundcolor: "#e5ecf6",
+      },
+      margin: {
+        l: 50,
+        r: 50,
+        t: 50,
+        b: 50,
+      },
+      plot_bgcolor: "#e5ecf6",
+      gridcolor: "#fff",
+      bgcolor: "#e5ecf6", // 设置背景颜色
+      autosize: true, // 开启自适应
+      showlegend: true, // 显示图例
+    };
+
+    // 创建临时目录
+    const tempDir = path.join(process.cwd(), "images");
+    await fs.ensureDir(tempDir);
+    const tempFilePath = path.join(
+      tempDir,
+      `temp_yew_error_bar_chart_${Date.now()}.png`
+    );
+
+    // 获取 plotly.js 的绝对路径
+    const plotlyPath = path.join(
+      process.cwd(),
+      "src",
+      "public",
+      "js",
+      "plotly-3.0.1.min.js"
+    );
+    const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
+
+    // 使用 Puppeteer 生成图表的截图
+    const browser = await puppeteer.launch({
+      headless: "new",
+      args: ["--no-sandbox", "--disable-setuid-sandbox"],
+    });
+    try {
+      const page = await browser.newPage();
+      const traces = [trace, legendTrace1, legendTrace2, legendTrace3];
+      const htmlContent = `
+        <!DOCTYPE html>
+        <html>
+          <head>
+            <meta charset="UTF-8">
+            <title>机组静态偏航误差值</title>
+            <script>${plotlyContent}</script>
+            <style>
+              body { margin: 0; }
+              #chart { width: 800px; height: 600px; }
+            </style>
+          </head>
+          <body>
+            <div id="chart"></div>
+            <script>
+              window.onload = function() {
+                Plotly.newPlot('chart', ${JSON.stringify(
+                  traces
+                )}, ${JSON.stringify(layout)}).then(() => {
+                  window.chartRendered = true;
+                });
+              };
+            </script>
+          </body>
+        </html>
+      `;
+      await page.setContent(htmlContent, { waitUntil: "networkidle0" });
+      await page.waitForFunction(() => window.chartRendered === true, {
+        timeout: 60000,
+      });
+      // 截图并保存到临时文件
+      const chartElement = await page.$("#chart");
+      await chartElement.screenshot({ path: tempFilePath, type: "png" });
+      // 上传图片到服务器
+      const formData = new FormData();
+      formData.append("file", fs.createReadStream(tempFilePath));
+      const response = await axios.post(
+        `${process.env.API_BASE_URL}/examples/upload`,
+        {
+          filePath: tempFilePath,
+          bucketName,
+          objectName,
+        }
+      );
+      console.log("上传成功:", response.data);
+      return response?.data?.url;
+    } catch (error) {
+      console.error("生成图表失败:", error);
+    } finally {
+      await browser.close();
+    }
+  } catch (error) {
+    console.error("发生错误:", error);
+  }
+};

+ 1 - 0
downLoadServer/src/server/utils/chartsCom/lineAndChildLine.js

@@ -199,6 +199,7 @@ export const generateLineAndChildLine = async (
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } finally {
       await browser.close();
     }

+ 2 - 2
downLoadServer/src/server/utils/chartsCom/lineChartsFen.js

@@ -17,8 +17,6 @@ export const generateLineChart = async (
   fieldEngineCode
 ) => {
   try {
-    console.log("开始生成折线图...");
-    console.log("数据:", data);
 
     // 创建临时目录
     const tempDir = path.join(process.cwd(), "images");
@@ -65,6 +63,7 @@ export const generateLineChart = async (
       });
 
       const finalData = [];
+      console.log(fieldEngineCode, "fieldEngineCode");
       sortedData.forEach((turbine) => {
         const color =
           turbine.engineCode === fieldEngineCode ? "#406DAB" : "#D3D3D3";
@@ -194,6 +193,7 @@ export const generateLineChart = async (
         `${process.env.API_BASE_URL}/examples/upload`,
         { filePath: tempFilePath, bucketName, objectName }
       );
+      return response?.data?.url;
     } finally {
       await browser.close();
     }

+ 2 - 2
downLoadServer/src/server/utils/chartsCom/powerMarkers2DCharts.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-04-28 14:15:23
- * @LastEditTime: 2025-05-06 10:33:43
+ * @LastEditTime: 2025-05-21 15:10:44
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /downLoadServer/src/server/utils/chartsCom/powerMarkers2DCharts.js
@@ -250,7 +250,7 @@ export const generatepowerMarkers2DCharts = async (
       );
       console.log(response.data, "response 上传结果"); // 打印上传结果
       // return response.data; // 返回上传结果
-      return "成功";
+      return response?.data?.url;
     } catch (error) {
       console.error("生成2D散点图失败:", error);
       throw error;

+ 49 - 0
downLoadServer/src/server/utils/chartsCom/productionIndicatorTotal.js

@@ -0,0 +1,49 @@
+// import fs from "fs-extra";
+// import path from "path";
+// import PizZip from "pizzip";
+// import Docxtemplater from "docxtemplater";
+// import { fileURLToPath } from "url";
+// import ImageModule from "docxtemplater-image-module-free";
+// const __filename = fileURLToPath(import.meta.url);
+// const __dirname = path.dirname(__filename);
+
+// export const getProductionIndicatorTotal = async (
+//   data,
+//   bucketName,
+//   objectName,
+//   fieldInfo
+// ) => {
+//   try {
+//     // 目标文件路径
+//     const targetFilePath = path.join(
+//       process.cwd(),
+//       "src",
+//       "public",
+//       "file",
+//       `${fieldInfo.companyName}.docx`
+//     );
+
+//     // 读取复制后的文件
+//     const content = await fs.readFile(targetFilePath, "binary");
+//     const zip = new PizZip(content);
+//     const doc = new Docxtemplater(zip, {
+//       /* options */
+//       paragraphLoop: true,
+//       linebreaks: true,
+//     });
+
+//     // 设置模板数据(行数据传 rows)
+//     doc.render({
+//       rows: data,
+//     });
+
+//     // 生成新 Word 文件
+//     const buffer = doc.getZip().generate({ type: "nodebuffer" });
+//     await fs.writeFile(targetFilePath, buffer);
+//     console.log(`文档生成成功:${targetFilePath}`);
+//     return data;
+//   } catch (error) {
+//     console.error("生成 Word 文档失败:", error);
+//     throw error;
+//   }
+// };

+ 166 - 8
downLoadServer/src/server/utils/chartsCom/yawErrorBarSum.js

@@ -1,8 +1,166 @@
-/*
- * @Author: your name
- * @Date: 2025-05-15 15:21:01
- * @LastEditTime: 2025-05-15 15:21:02
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /downLoadServer/src/server/utils/chartsCom/yawErrorBarSum.js
- */
+import puppeteer from "puppeteer";
+import fs from "fs-extra";
+import path from "path";
+import FormData from "form-data";
+import axios from "axios"; // 导入 axios
+import { colorSchemes } from "../colors.js";
+import { text } from "stream/consumers";
+
+export const getYawErrorBarSumCharts = async (
+  data,
+  bucketName,
+  objectName,
+  analysisTypeCode
+) => {
+  try {
+    // 提取静态偏航误差值和机组数量
+    let a = [];
+    let b = [];
+    let c = [];
+    data.map((item) => {
+      if (item["[0,3]"] != "0.0") {
+        a.push(item["[0,3]"]);
+      }
+      if (item["(3,5]"] != "0.0") {
+        b.push(item["(3,5]"]);
+      }
+      if (item["(5, )"] != "0.0") {
+        c.push(item["(5, )"]);
+      }
+    });
+
+    const xData = ["(0,3]", "(3,5]", "(>5]"]; // 偏航误差区间
+    const yData = [a.length, b.length, c.length]; // 各区间的机组数量
+
+    // 每个柱子的颜色
+    const colors = [
+      "#8AC8BE", // (0, 3] 蓝色
+      "#407DB3", // (3, 5] 绿色
+      "#1B2973", // (5, ∞] 红色
+    ];
+
+    const trace = {
+      x: xData, // 横坐标数据
+      y: yData, // 纵坐标数据
+      type: "bar", // 当前图表类型
+      marker: {
+        color: colors, // 为每个柱子分配不同的颜色
+      },
+      // hovertemplate:
+      //   `偏航误差值:` + ` %{x} <br> ` + `台数:` + "%{y} <br> <extra></extra>",
+    };
+
+    const layout = {
+      title: {
+        text: "静态偏航误差的绝对值机组台数分布情况",
+        font: {
+          size: 16,
+          weight: "bold",
+        },
+      }, // 图表标题
+      xaxis: {
+        title: { text: "静态偏航误差值(度)" }, // 横坐标标题
+        gridcolor: "rgb(255,255,255)",
+        tickcolor: "rgb(255,255,255)",
+        backgroundcolor: "#e5ecf6",
+      },
+      yaxis: {
+        title: {
+          text: "台数",
+        }, // 纵坐标标题
+        gridcolor: "rgb(255,255,255)",
+        tickcolor: "rgb(255,255,255)",
+        backgroundcolor: "#e5ecf6",
+      },
+      margin: {
+        l: 50,
+        r: 50,
+        t: 50,
+        b: 50,
+      },
+      autosize: true, // 开启自适应
+      // showlegend: true, // 显示图例
+      plot_bgcolor: "#e5ecf6",
+      gridcolor: "#fff",
+      bgcolor: "#e5ecf6", // 设置背景颜色
+    };
+
+    // 创建临时目录
+    const tempDir = path.join(process.cwd(), "images");
+    await fs.ensureDir(tempDir);
+    const tempFilePath = path.join(
+      tempDir,
+      `temp_yaw_error_bar_sum_chart_${Date.now()}.png`
+    );
+    // 获取 plotly.js 的绝对路径
+    const plotlyPath = path.join(
+      process.cwd(),
+      "src",
+      "public",
+      "js",
+      "plotly-3.0.1.min.js"
+    );
+    const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
+
+    // 使用 Puppeteer 生成图表的截图
+    const browser = await puppeteer.launch({
+      headless: "new",
+      args: ["--no-sandbox", "--disable-setuid-sandbox"],
+    });
+    try {
+      const page = await browser.newPage();
+      const htmlContent = `
+        <!DOCTYPE html>
+        <html>
+          <head>
+            <meta charset="UTF-8">
+            <title>静态偏航误差值</title>
+            <script>${plotlyContent}</script>
+            <style>
+              body { margin: 0; }
+              #chart { width: 800px; height: 600px; }
+            </style>
+          </head>
+          <body>
+            <div id="chart"></div>
+            <script>
+              window.onload = function() {
+                Plotly.newPlot('chart', [${JSON.stringify(
+                  trace
+                )}], ${JSON.stringify(layout)}).then(() => {
+                  window.chartRendered = true;
+                });
+              };
+            </script>
+          </body>
+        </html>
+      `;
+      await page.setContent(htmlContent, { waitUntil: "networkidle0" });
+      await page.waitForFunction(() => window.chartRendered === true, {
+        timeout: 60000,
+      });
+      // 截图并保存到临时文件
+      const chartElement = await page.$("#chart");
+      await chartElement.screenshot({ path: tempFilePath, type: "png" });
+      // 上传图片到服务器
+      const formData = new FormData();
+      formData.append("file", fs.createReadStream(tempFilePath));
+      const response = await axios.post(
+        `${process.env.API_BASE_URL}/examples/upload`,
+        {
+          filePath: tempFilePath,
+          bucketName,
+          objectName,
+        }
+      );
+      return response.data.url;
+      console.log("上传成功:", response.data);
+    } catch (error) {
+      console.error("生成图表失败:", error);
+    } finally {
+      await browser.close();
+    }
+  } catch (error) {
+    console.error("发生错误:", error);
+  }
+};

+ 14 - 2
downLoadServer/src/server/utils/chartsCom/yawErrorLine.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-05-14 10:49:00
- * @LastEditTime: 2025-05-14 11:17:48
+ * @LastEditTime: 2025-05-21 15:11:44
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /downLoadServer/src/server/utils/chartsCom/yawErrorLine.js
@@ -21,6 +21,15 @@ export const generateYawErrorLine = async (
   try {
     const data = [];
     const colors = [...colorSchemes[0].colors]; // 生成颜色
+    // 获取 plotly.js 的绝对路径
+    const plotlyPath = path.join(
+      process.cwd(),
+      "src",
+      "public",
+      "js",
+      "plotly-3.0.1.min.js"
+    );
+    const plotlyContent = await fs.readFile(plotlyPath, "utf-8");
 
     chartData &&
       chartData.data &&
@@ -122,7 +131,9 @@ export const generateYawErrorLine = async (
         <!DOCTYPE html>
         <html>
           <head>
-            <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
+            <meta charset="UTF-8">
+            <title>静态偏航折线分图</title>
+            <script>${plotlyContent}</script>
             <style>
               body { margin: 0; }
               #chart { width: 800px; height: 600px; }
@@ -165,6 +176,7 @@ export const generateYawErrorLine = async (
       );
 
       console.log("上传成功:", response.data);
+      return response?.data?.url;
     } catch (error) {
       console.error("生成折线图失败:", error);
       throw error;

+ 168 - 0
downLoadServer/src/server/utils/copyFileCsv.js

@@ -0,0 +1,168 @@
+import fs from "fs-extra";
+import path from "path";
+import PizZip from "pizzip";
+import Docxtemplater from "docxtemplater";
+import { fileURLToPath } from "url";
+import ImageModule from "docxtemplater-image-module-free";
+import axios from "axios";
+import sizeOf from "image-size";
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+// 读取本地或远程图片,返回 Buffer
+const getImageFromUrl = async (url) => {
+  if (typeof url !== "string") {
+    throw new TypeError(`图片 URL 应为字符串,但实际是 ${typeof url}`);
+  }
+
+  if (url.startsWith("http")) {
+    const safeUrl = url.replace(/#/g, "%23"); // 处理 URL 中的 #
+    const response = await axios.get(safeUrl, { responseType: "arraybuffer" });
+    const buffer = Buffer.from(response.data, "binary");
+
+    if (buffer.length < 1000) {
+      console.warn(`⚠️ 图像可能无效或过小: ${url}`);
+    }
+
+    return buffer;
+  } else {
+    return fs.readFileSync(url); // 本地图片
+  }
+};
+
+// 预加载所有图片为 Buffer
+const preloadAllImages = async (chartsImages) => {
+  const allUrls = Object.values(chartsImages).flat(); // 扁平化为图片 URL 列表
+  const imageMap = {};
+
+  for (const url of allUrls) {
+    if (typeof url !== "string" || !url.trim()) {
+      console.warn("⚠️ 非法图片 URL:", url);
+      continue;
+    }
+
+    try {
+      const buffer = await getImageFromUrl(url);
+      if (!buffer || buffer.length === 0) {
+        console.warn("⚠️ 获取的图片 buffer 长度为 0:", url);
+        continue;
+      }
+      imageMap[url] = buffer;
+    } catch (e) {
+      console.warn("⚠️ 加载图片失败:", url, e.message);
+    }
+  }
+
+  return imageMap;
+};
+
+// 生成 Word 文件
+export const copyFileDocx = async (fieldInfo, chartsImages) => {
+  try {
+    const sourceFilePath = path.join(
+      process.cwd(),
+      "src",
+      "public",
+      "file",
+      "副本XXX风电场可靠性和能效双提升数据分析报告(模板).docx"
+    );
+
+    const targetFilePath = path.join(
+      process.cwd(),
+      "src",
+      "public",
+      "file",
+      `${fieldInfo.companyName}.docx`
+    );
+
+    // 拷贝模板
+    await fs.copy(sourceFilePath, targetFilePath);
+    const content = await fs.readFile(targetFilePath, "binary");
+    const zip = new PizZip(content);
+
+    // 预加载所有图片
+    const imageBufferMap = await preloadAllImages(chartsImages);
+
+    // 配置 image module
+    const imageModule = new ImageModule({
+      centered: true,
+      getImage: (tagValue) => {
+        const buffer = imageBufferMap[tagValue];
+        if (!buffer) {
+          throw new Error(`未找到图片 Buffer: ${tagValue}`);
+        }
+        return buffer;
+      },
+
+      getSize: (imgBuffer) => {
+        try {
+          const dimensions = sizeOf(imgBuffer);
+          const maxWidth = 500;
+          const ratio = maxWidth / dimensions.width;
+          return [maxWidth, dimensions.height * ratio];
+        } catch (e) {
+          console.error("❌ 获取图片尺寸失败", e);
+          console.error("buffer 长度:", imgBuffer.length);
+          throw new Error("图片尺寸获取失败,可能是非法图片或 Buffer 损坏");
+        }
+      },
+    });
+
+    const doc = new Docxtemplater(zip, {
+      paragraphLoop: true,
+      linebreaks: true,
+      modules: [imageModule],
+    });
+
+    const now = new Date();
+    const year = now.getFullYear();
+    const month = String(now.getMonth() + 1).padStart(2, "0");
+
+    // 构建模板图像字段对象
+    const imageTagData = {};
+    for (const [tag, urlList] of Object.entries(chartsImages)) {
+      if (Array.isArray(urlList)) {
+        imageTagData[tag] = urlList.map((url) => ({ image: url }));
+      } else {
+        console.warn(`⚠️ 无效的 urlList: ${tag}`, urlList);
+        imageTagData[tag] = []; // 或 throw error
+      }
+    }
+    console.log(chartsImages.rows, "chartsImages");
+
+    const renderData = {
+      Year_now: year,
+      Month_now: month,
+      Province: fieldInfo.provinceName,
+      Wind_farm: fieldInfo.fieldName,
+      Wind_turbine: fieldInfo.engineMillTypes.join(","),
+      Overview_of_the_Wind_Farm: `${fieldInfo.fieldName}位于${
+        fieldInfo.provinceName
+      }${fieldInfo.cityName},海拔高度为${fieldInfo.elevationHeight} 米,经度${
+        fieldInfo.longitude
+      }°,纬度${fieldInfo.latitude}°。风场总容量为${
+        fieldInfo.ratedCapacityNumber
+      } MW,共安装${
+        fieldInfo.engineCount
+      } 台风机,机型包括${fieldInfo.engineMillTypes?.join(",")}`,
+      ...imageTagData, // 图像数据动态插入
+      rows: chartsImages.rows,
+      windTurbineRows: chartsImages.windTurbineRows,
+      faultRows: chartsImages.faultRows,
+      yawErrorRows: chartsImages.yawErrorRows,
+    };
+
+    // 渲染 Word 模板
+    doc.render(renderData);
+
+    // 保存生成的文档
+    const buffer = doc.getZip().generate({ type: "nodebuffer" });
+    await fs.writeFile(targetFilePath, buffer);
+
+    return `✅ 文档生成成功:${targetFilePath}`;
+  } catch (error) {
+    console.error("❌ 生成 Word 文档失败:", error);
+    throw error;
+  }
+};

+ 10 - 9
src/views/overview/components/fault_all/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-13 13:56:55
- * @LastEditTime: 2025-03-21 14:39:23
+ * @LastEditTime: 2025-05-16 15:08:41
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/fault_all/index.vue
@@ -305,15 +305,16 @@ export default {
                         .filter((row) => Object.keys(row).length)
                         .slice(0, result.data.length - 1),
                     });
-                  } else {
-                    //分机型故障统计处理
-                    this.fenFaultCsvHeader.push(Object.keys(result.data[0]));
-                    this.fenFaultCsvData.push({
-                      data: result.data
-                        .filter((row) => Object.keys(row).length)
-                        .slice(0, result.data.length - 1),
-                    });
                   }
+                  //  else {
+                  //   //分机型故障统计处理
+                  //   this.fenFaultCsvHeader.push(Object.keys(result.data[0]));
+                  //   this.fenFaultCsvData.push({
+                  //     data: result.data
+                  //       .filter((row) => Object.keys(row).length)
+                  //       .slice(0, result.data.length - 1),
+                  //   });
+                  // }
                 }
               },
               error: (error) => {

+ 242 - 46
src/views/performance/assetssMag.vue

@@ -302,13 +302,13 @@
           min-width="300"
         >
           <template slot-scope="scope">
-            <!-- <el-button
+            <el-button
               @click="handleDownLoadChart(scope.row)"
               type="text"
               size="small"
             >
               下载报告
-            </el-button> -->
+            </el-button>
             <el-button
               @click="abnormalDialog(scope.row, '上传报告')"
               type="text"
@@ -476,6 +476,7 @@ export default {
   },
   data() {
     return {
+      fileDataList: {},
       fieldInfo: {}, //风场信息
       firstLoad: false, // 是否是第一次加载
       fieldCodeList: [],
@@ -549,17 +550,52 @@ export default {
     //   console.log(row.fieldCode, "row");
     //   await this.getAllAnalysis(row.batchCode);
     //   await this.getFieldDetail(row.batchCode);
-    //   const res = await axios.post(
-    //     "/downLoadChart/chartServer/charts/yawErrorLine",
+
+    //   const diagramRelations = [
     //     {
-    //       fieldEngineCode: "WOG00623", //lineChartFen
-    //       bucketName: "",
-    //       // row.fieldCode + "/" + row.batchCode + "/" + item.analysisTypeCode, //桶名称
-    //       objectName: "", //在 MinIO 中的文件名
-    //       fieldInfo: this.fieldInfo,
+    //       batchCode: "WOF039800012-WOB000001",
+    //       analysisTypeCode: "production_indicator",
+    //       analysisTypeName: "机组指标",
     //       fileAddr:
+    //         "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/production_indicator/manual/WT2000%252F93-production-indicator.csv",
+    //       autoAnalysis: null,
+    //       createTime: "2025-01-21 16:35:46",
+    //       engineTypeCode: "WEM00012",
+    //     },
+    //     // {
+    //     //   batchCode: "WOF039800012-WOB000001",
+    //     //   analysisTypeCode: "production_indicator",
+    //     //   analysisTypeName: "机组指标",
+    //     //   fileAddr:
+    //     //     "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/production_indicator/manual/WT2000%252F100-production-indicator.csv",
+    //     //   autoAnalysis: null,
+    //     //   createTime: "2025-01-21 16:35:46",
+    //     //   engineTypeCode: "WEM00013",
+    //     // },
+    //     // {
+    //     //   batchCode: "WOF039800012-WOB000001",
+    //     //   analysisTypeCode: "production_indicator",
+    //     //   analysisTypeName: "机组指标",
+    //     //   fileAddr:
+    //     //     "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/production_indicator/manual/WT2000%252F110-production-indicator.csv",
+    //     //   autoAnalysis: null,
+    //     //   createTime: "2025-01-21 16:35:46",
+    //     //   engineTypeCode: "WEM00018",
+    //     // },
+    //   ];
+    //   diagramRelations.map(async (item) => {
+    //     const res = await axios.post(
+    //       "/downLoadChart/chartServer/charts/radarChart",
+    //       {
+    //         fieldEngineCode: item.fieldEngineCode ? item.fieldEngineCode : "", //lineChartFen
+    //         bucketName: "bucket-zhzn",
+    //         // row.fieldCode + "/" + row.batchCode + "/" + item.analysisTypeCode, //桶名称
+    //         objectName: "charts/111.jpg", //在 MinIO 中的文件名
+    //         fieldInfo: this.fieldInfo,
+    //         fileAddr: item.fileAddr,
+    //         chartType: "radar",
     //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/wind_speed_frequency/manual/wind_Speed_Frequency%2302.json", //barChart  url:bar
-    //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/cp/manual/%2320.json", //lineChartFen  url:line
+    //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/cp_windspeed/manual/%2319.json", //lineChartFen  url:line
     //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/cp/manual/WEM00013.json", //lineAndChartLine  url:lineAndChildLine
     //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/data_integrity_second/manual/Data_Integrity_Of_Second_Analyst.json", //HeatmapCharts  url:heatmap
     //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/speed_torque/manual/total_3D_WEM00012.json", //3DDrawingChart  url:3DDrawingChart
@@ -574,25 +610,49 @@ export default {
     //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/tsr_trend/manual/%2302.json", //boxMarkersCharts
     //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/temperature_large_components/manual/GeneratorTemperature/%2321.json", //generatorTemperature
     //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/wind_direction_frequency/manual/wind_direction_frequency%2318.json", //windRoseChart
-    //         "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/yaw_error/manual/%2320.json", //yawErrorLine
-    //     }
-    //   );
-    //   // this.allAnalysis.map(async (item, ind) => {
+    //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/yaw_error/manual/%2320.json", //yawErrorLine
+    //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/fault/manual/total_fault_result.csv", //faultAllChart //全场故障
+    //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/fault/manual/turbine_fault_result.csv", //faultUnitChart //机组故障
+    //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/yaw_error/manual/yaw_error_result.csv", //静态偏航总图 //yawErrorBarSumChart
+    //         // "http://192.168.50.233:6900/wof039800012/WOF039800012-WOB000001/production_indicator/manual/production_indicator_total.csv", //全场指标 productionIndicatorTotal
+    //       }
+    //     );
+    //   });
 
-    //   //   console.log(res, "res linechart");
-    //   // });
+    //   await axios.post("/downLoadChart/chartServer/charts/CopyFileCsv", {
+    //     fieldInfo: this.fieldInfo,
+    //     rows: [
+    //       {
+    //         Qdr: "-70352582.72",
+    //         Qp: "70352582.72",
+    //         Rdr: "0",
+    //         Thc: "1675.06",
+    //       },
+    //     ],
+    //     "zn-techcn-replace-tags-production_indicator_unit-generalFiles": [
+    //       "http://192.168.50.233:6900/bucket-zhzn/charts/#03.jpg",
+    //       "http://192.168.50.233:6900/bucket-zhzn/charts/#05.jpg",
+    //       "http://192.168.50.233:6900/bucket-zhzn/charts/#06.jpg",
+    //       "http://192.168.50.233:6900/bucket-zhzn/charts/#08.jpg",
+    //       "http://192.168.50.233:6900/bucket-zhzn/charts/#09.jpg",
+    //       "http://192.168.50.233:6900/bucket-zhzn/charts/#14.jpg",
+    //       "http://192.168.50.233:6900/bucket-zhzn/charts/#17.jpg",
+    //     ],
+    //   });
     // },
-    //获取 风机信息
+
+    // 获取 风机信息
+
     async handleDownLoadChart(row) {
       await this.getAllAnalysis(row.batchCode);
       await this.getFieldDetail(row.batchCode);
+
       const limit = pLimit(5); // 限制同时并发的请求数量为 5
       const tasks = [];
       for (const itemAnalysis of this.allAnalysis) {
         const filterAnalysis = allAnalysisType.filter(
           (itemType) => itemType.typeName === itemAnalysis.analysisTypeName
         )[0];
-
         if (itemAnalysis.generalFiles) {
           //这里过滤的是发电机温度的类型 在url 中是否能找到filterFileAddr
           for (const itemField of filterAnalysis.filterFileAddr
@@ -602,20 +662,105 @@ export default {
                   item.fileAddr.includes(filterAnalysis.filterFileAddr)
                 ) || []
             : itemAnalysis.generalFiles) {
-            tasks.push(
-              limit(() =>
-                this.postChartData(
-                  filterAnalysis.generalFiles.urlType,
-                  row,
-                  itemAnalysis,
-                  itemField,
-                  filterAnalysis
+            //静态偏航误差 --通过allAnalysisType.js文件配置实现需求
+            if (Array.isArray(filterAnalysis.generalFiles.urlType)) {
+              filterAnalysis.generalFiles.urlType.map(
+                (itemUrlType, indUrlType) => {
+                  tasks.push(
+                    limit(() =>
+                      this.postChartData(
+                        itemUrlType,
+                        row,
+                        itemAnalysis,
+                        itemField,
+                        filterAnalysis,
+                        "generalFiles"
+                      )
+                    )
+                  );
+                }
+              );
+            } else if (filterAnalysis.typeCode === "fault") {
+              if (itemField.fileAddr.includes("turbine_fault_result")) {
+                if (itemField.engineTypeCode === "turbine_fault_result") {
+                  tasks.push(
+                    limit(() =>
+                      this.postChartData(
+                        "faultUnitChart",
+                        row,
+                        itemAnalysis,
+                        itemField,
+                        filterAnalysis,
+                        "generalFiles"
+                      )
+                    )
+                  );
+                }
+              } else {
+                if (itemField.engineTypeCode === "total_fault_result") {
+                  tasks.push(
+                    limit(() =>
+                      this.postChartData(
+                        "faultAllChart",
+                        row,
+                        itemAnalysis,
+                        itemField,
+                        filterAnalysis,
+                        "generalFiles"
+                      )
+                    )
+                  );
+                }
+              }
+            } else if (filterAnalysis.typeCode === "production_indicator") {
+              //总图全场
+              if (
+                itemField.fileAddr.includes(
+                  filterAnalysis.generalFiles.FileTypeFromUrl
                 )
-              )
-            );
+              ) {
+                tasks.push(
+                  limit(() =>
+                    this.postChartData(
+                      filterAnalysis.generalFiles.urlType,
+                      row,
+                      itemAnalysis,
+                      itemField,
+                      filterAnalysis,
+                      "generalFiles"
+                    )
+                  )
+                );
+              } else {
+                tasks.push(
+                  limit(() =>
+                    this.postChartData(
+                      "radarChart",
+                      row,
+                      itemAnalysis,
+                      itemField,
+                      filterAnalysis,
+                      "generalFiles"
+                    )
+                  )
+                );
+              }
+            } else {
+              tasks.push(
+                limit(() =>
+                  this.postChartData(
+                    filterAnalysis.generalFiles.urlType,
+                    row,
+                    itemAnalysis,
+                    itemField,
+                    filterAnalysis,
+                    "generalFiles"
+                  )
+                )
+              );
+            }
           }
         }
-
         if (itemAnalysis.diagramRelations) {
           for (const itemField of filterAnalysis.filterFileAddr
             ? itemAnalysis.diagramRelations
@@ -634,7 +779,7 @@ export default {
                 ? filterAnalysis.diagramRelations.urlType[0]
                 : filterAnalysis.diagramRelations.urlType[1]
               : filterAnalysis.diagramRelations.urlType;
-            console.log("urlType", filterAnalysis.typeName, urlType);
+            // console.log("urlType", filterAnalysis.typeName, urlType);
             tasks.push(
               limit(() =>
                 this.postChartData(
@@ -642,36 +787,42 @@ export default {
                   row,
                   itemAnalysis,
                   itemField,
-                  filterAnalysis
+                  filterAnalysis,
+                  "diagramRelations"
                 )
               )
             );
           }
         }
       }
-
       await Promise.all(tasks);
+
+      await axios.post("/downLoadChart/chartServer/charts/CopyFileCsv", {
+        fieldInfo: this.fieldInfo,
+        ...this.fileDataList,
+      });
+
+      console.log("生成成功:", this.fileDataList);
       console.log("全部图表生成请求已完成");
     },
 
-    async postChartData(urlType, row, itemAnalysis, itemField, filterAnalysis) {
+    async postChartData(
+      urlType,
+      row,
+      itemAnalysis,
+      itemField,
+      filterAnalysis,
+      typeChart
+    ) {
       try {
-        console.log(
-          filterAnalysis.filterFileAddr +
-            "/" +
-            itemField.fieldEngineName +
-            ".png",
-          "filterAnalysis.filterFileAddr"
-        );
         const objectname =
           itemAnalysis.analysisTypeCode === "temperature_large_components"
             ? filterAnalysis.filterFileAddr +
               "/" +
               itemField.fieldEngineName +
-              ".png"
-            : urlType + itemField.fieldEngineName + ".png" ||
-              urlType + itemField.engineTypeCode + ".png";
-        console.log(objectname, "objectname");
+              ".jpg"
+            : urlType + itemField.fieldEngineName + ".jpg" ||
+              urlType + itemField.engineTypeCode + ".jpg";
         const res = await axios.post(
           `/downLoadChart/chartServer/charts/${urlType}`,
           {
@@ -682,14 +833,59 @@ export default {
               objectname,
             fieldInfo: this.fieldInfo,
             fileAddr: itemField.fileAddr,
+            chartType:
+              filterAnalysis.typeDocxName === "production_indicator_unit"
+                ? "radar"
+                : urlType,
           }
         );
-        console.log("生成成功:", res);
+        let key = `zn-techcn-replace-tags-${filterAnalysis.typeDocxName}-${typeChart}`;
+        if (urlType === "yawErrorBarSumChart") {
+          key = `zn-techcn-replace-tags-${filterAnalysis.typeDocxName}-generalFiles2`;
+
+          if (!this.fileDataList["yawErrorRows"]) {
+            this.$set(this.fileDataList, "yawErrorRows", []); // Vue 2 中响应式设置对象属性
+          }
+          this.fileDataList["yawErrorRows"] = res?.data?.data?.data;
+        } else if (urlType === "yawErrorChart") {
+          key = `zn-techcn-replace-tags-${filterAnalysis.typeDocxName}-generalFiles1`;
+        }
+        if (filterAnalysis.typeDocxName === "production_indicator_all") {
+          if (!this.fileDataList["rows"]) {
+            this.$set(this.fileDataList, "rows", []); // Vue 2 中响应式设置对象属性
+          }
+          this.fileDataList["rows"] = res?.data?.data?.data;
+        }
+        //
+        if (itemField.engineTypeCode === "total_fault_result") {
+          if (!this.fileDataList["faultRows"]) {
+            this.$set(this.fileDataList, "faultRows", []); // Vue 2 中响应式设置对象属性
+          }
+          this.fileDataList["faultRows"] = res?.data?.data?.data;
+        }
+        if (itemField.engineTypeCode === "turbine_fault_result") {
+          if (!this.fileDataList["windTurbineRows"]) {
+            this.$set(this.fileDataList, "windTurbineRows", []); // Vue 2 中响应式设置对象属性
+          }
+          this.fileDataList["windTurbineRows"] = res?.data?.data?.data;
+        }
+        if (filterAnalysis.typeDocxName === "production_indicator_unit") {
+          if (!this.fileDataList[key]) {
+            this.$set(this.fileDataList, key, []); // Vue 2 中响应式设置对象属性
+          }
+          res?.data?.data?.imageUrls.map((imgval) => {
+            this.fileDataList[key].push(imgval);
+          });
+        } else {
+          if (!this.fileDataList[key]) {
+            this.$set(this.fileDataList, key, []); // Vue 2 中响应式设置对象属性
+          }
+          this.fileDataList[key].push(res?.data?.data?.imageUrl);
+        }
       } catch (err) {
         console.error("生成失败:", err);
       }
     },
-
     getFileTypeFromUrl(url, keyword) {
       return url.includes(keyword) ? keyword : "Unknown";
     },

+ 7 - 2
src/views/performance/components/PlotlyCharts.vue

@@ -195,9 +195,11 @@ export default {
 
       const data = this.powerCurveData.turbines.map((turbine, index) => ({
         x: turbine.xData,
-        y: processNullValues(turbine.yData),
+        // y: processNullValues(turbine.yData),
+        y: turbine.yData,
         mode: "lines",
         name: turbine.enginName,
+        connectgaps: false,
         fill: this.chartType === "line" ? "none" : "tonexty",
         line: {
           color:
@@ -308,8 +310,10 @@ export default {
 
           const trace = {
             x: turbine.xData,
-            y: turbine.yData.map((val) => (val !== null ? val : 0.0)),
+            y: turbine.yData,
+            // y: turbine.yData.map((val) => (val !== null ? val : 0.0)),
             mode: "lines",
+            // connectgaps: false,
             name: turbine.enginName,
             fill: this.chartType === "line" ? "none" : "tonexty",
             line: {
@@ -338,6 +342,7 @@ export default {
             color: "red",
             width: 1, // 设置线条的宽度为1
           },
+          // connectgaps: false,
           marker: { color: "red", size: 4 },
           hovertemplate:
             `风速: %{x} m/s<br>合同功率: %{y} kW<br>` +

+ 1 - 115
src/views/performance/components/chartsCom/FaultAll.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-15 14:24:59
- * @LastEditTime: 2025-03-14 19:05:37
+ * @LastEditTime: 2025-05-16 11:14:32
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/FaultAll.vue
@@ -148,120 +148,6 @@ export default {
       // 渲染图表
       Plotly.newPlot(this.$refs.chart, [barTrace, lineTrace], layout);
     },
-
-    // renderChart() {
-    //   var trace1 = {
-    //     x: [
-    //       "Jan",
-    //       "Feb",
-    //       "Mar",
-    //       "Apr",
-    //       "May",
-    //       "Jun",
-    //       "Jul",
-    //       "Aug",
-    //       "Sep",
-    //       "Oct",
-    //       "Nov",
-    //       "Dec",
-    //     ],
-    //     y: [
-    //       2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3,
-    //     ],
-    //     type: "bar",
-    //     name: "Evaporation",
-    //     marker: { color: "#5470C6" },
-    //   };
-
-    //   var trace2 = {
-    //     x: [
-    //       "Jan",
-    //       "Feb",
-    //       "Mar",
-    //       "Apr",
-    //       "May",
-    //       "Jun",
-    //       "Jul",
-    //       "Aug",
-    //       "Sep",
-    //       "Oct",
-    //       "Nov",
-    //       "Dec",
-    //     ],
-    //     y: [
-    //       2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3,
-    //     ],
-    //     type: "bar",
-    //     name: "Precipitation",
-    //     yaxis: "y2", // 使用第二个 Y 轴
-    //     marker: { color: "#91CC75" },
-    //   };
-
-    //   var trace3 = {
-    //     x: [
-    //       "Jan",
-    //       "Feb",
-    //       "Mar",
-    //       "Apr",
-    //       "May",
-    //       "Jun",
-    //       "Jul",
-    //       "Aug",
-    //       "Sep",
-    //       "Oct",
-    //       "Nov",
-    //       "Dec",
-    //     ],
-    //     y: [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2],
-    //     type: "scatter",
-    //     mode: "lines+markers",
-    //     name: "Temperature",
-    //     line: { color: "#EE6666" },
-    //     yaxis: "y3", // 使用第三个 Y 轴
-    //   };
-
-    //   var layout = {
-    //     title: "Evaporation, Precipitation, and Temperature",
-    //     xaxis: {
-    //       title: "Month",
-    //     },
-    //     yaxis: {
-    //       title: "Evaporation",
-    //       titlefont: { color: "#5470C6" },
-    //       tickfont: { color: "#5470C6" },
-    //       side: "left",
-    //       showline: true,
-    //       linecolor: "#5470C6",
-    //     },
-    //     yaxis2: {
-    //       title: "Precipitation",
-    //       titlefont: { color: "#91CC75" },
-    //       tickfont: { color: "#91CC75" },
-    //       overlaying: "y",
-    //       side: "right",
-    //       showline: true,
-    //       linecolor: "#91CC75",
-    //     },
-    //     yaxis3: {
-    //       title: "Temperature (°C)",
-    //       titlefont: { color: "#EE6666" },
-    //       tickfont: { color: "#EE6666" },
-    //       overlaying: "y",
-    //       side: "right",
-    //       position: 0.85, // 调整右侧 Y 轴的位置
-    //       showline: true,
-    //       linecolor: "#EE6666",
-    //     },
-    //     showlegend: true,
-    //     margin: {
-    //       t: 50,
-    //       b: 50,
-    //       r: 100,
-    //     },
-    //   };
-
-    //   Plotly.newPlot(this.$refs.chart, [trace1, trace2, trace3], layout);
-    // },
   },
 };
 </script>

+ 0 - 8
src/views/performance/components/chartsCom/FaultUnit.vue

@@ -1,11 +1,3 @@
-<!--
- * @Author: your name
- * @Date: 2025-01-15 15:49:57
- * @LastEditTime: 2025-04-11 16:55:00
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /performance-test/src/views/performance/components/chartsCom/FaultUntal.vue
--->
 <template>
   <div>
     <div ref="chart" style="width: 100%; height: 400px"></div>

+ 0 - 2
src/views/performance/components/chartsCom/HeatmapCharts.vue

@@ -89,11 +89,9 @@ export default {
             cancelToken: this.cancelToken.token,
           });
           this.chartData = resultChartsData.data;
-
           this.initData[0].x = this.chartData.data[0].xData;
           this.initData[0].y = this.chartData.data[0].yData;
           this.initData[0].z = this.chartData.data[0].ZData;
-
           nextTick(() => {
             this.initcharts();
           });

+ 1 - 1
src/views/performance/components/chartsCom/yawErrorBarSum.vue

@@ -148,7 +148,7 @@ export default {
           b: 50,
         },
         autosize: true, // 开启自适应
-        showlegend: true, // 显示图例
+        // showlegend: true, // 显示图例
         plot_bgcolor: "#e5ecf6",
         gridcolor: "#fff",
         bgcolor: "#e5ecf6", // 设置背景颜色

+ 58 - 14
src/views/performance/js/allAnalysisType.js

@@ -1,7 +1,7 @@
 /*
  * @Author: your name
  * @Date: 2025-05-06 17:01:14
- * @LastEditTime: 2025-05-14 14:40:13
+ * @LastEditTime: 2025-05-22 14:41:36
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/js/allAnalysisType.js
@@ -12,6 +12,7 @@ export const allAnalysisType = [
     id: 101,
     parentId: 1,
     typeCode: "data_integrity_minute",
+    typeDocxName: "data_integrity_minute",
     typeFlag: "minute",
     generalFiles: {
       urlType: "heatmap",
@@ -25,6 +26,7 @@ export const allAnalysisType = [
     id: 102,
     parentId: 1,
     typeCode: "data_integrity_second",
+    typeDocxName: "data_integrity_second",
     typeFlag: "second",
     generalFiles: {
       urlType: "heatmap",
@@ -38,6 +40,7 @@ export const allAnalysisType = [
     id: 103,
     parentId: 2,
     typeCode: "wind_speed_frequency",
+    typeDocxName: "wind_speed_frequency",
     typeFlag: "minute",
     generalFiles: {
       urlType: "bar",
@@ -51,12 +54,13 @@ export const allAnalysisType = [
     id: 104,
     parentId: 2,
     typeCode: "wind_direction_frequency",
+    typeDocxName: "wind_direction_frequency",
     typeFlag: "minute",
     generalFiles: {
-      urlType: "radarChart",
+      urlType: "",
     },
     diagramRelations: {
-      urlType: "radarChart",
+      urlType: "WindRoseChart",
     },
   },
   {
@@ -64,6 +68,7 @@ export const allAnalysisType = [
     id: 105,
     parentId: 2,
     typeCode: "wind_speed",
+    typeDocxName: "wind_speed",
     typeFlag: "minute",
     generalFiles: {
       urlType: "bar",
@@ -78,6 +83,7 @@ export const allAnalysisType = [
     parentId: 3,
     typeCode: "power_curve",
     typeFlag: "minute",
+    typeDocxName: "power_curve",
     generalFiles: {
       urlType: "",
     },
@@ -91,6 +97,7 @@ export const allAnalysisType = [
     parentId: 3,
     typeCode: "power_scatter_2D",
     typeFlag: "minute",
+    typeDocxName: "power_scatter_2D",
     generalFiles: {
       urlType: "",
     },
@@ -103,6 +110,7 @@ export const allAnalysisType = [
     id: 108,
     parentId: 3,
     typeCode: "power_scatter",
+    typeDocxName: "power_scatter",
     typeFlag: "minute",
     generalFiles: {
       urlType: "",
@@ -117,8 +125,9 @@ export const allAnalysisType = [
     parentId: 4,
     typeCode: "rated_power_windspeed",
     typeFlag: "minute",
+    typeDocxName: "rated_power_windspeed",
     generalFiles: {
-      urlType: "",
+      urlType: "boxLineCharts",
     },
     diagramRelations: {
       urlType: "",
@@ -129,9 +138,10 @@ export const allAnalysisType = [
     id: 110,
     parentId: 4,
     typeCode: "rated_windspeed",
+    typeDocxName: "rated_windspeed",
     typeFlag: "minute",
     generalFiles: {
-      urlType: "",
+      urlType: "bar",
     },
     diagramRelations: {
       urlType: "",
@@ -142,6 +152,7 @@ export const allAnalysisType = [
     id: 111,
     parentId: 5,
     typeCode: "cp",
+    typeDocxName: "cp",
     typeFlag: "second",
     generalFiles: {
       urlType: "lineAndChildLine",
@@ -155,6 +166,7 @@ export const allAnalysisType = [
     id: 112,
     parentId: 5,
     typeCode: "cp_windspeed",
+    typeDocxName: "cp_windspeed",
     typeFlag: "second",
     generalFiles: {
       urlType: "lineAndChildLine",
@@ -168,12 +180,13 @@ export const allAnalysisType = [
     id: 113,
     parentId: 5,
     typeCode: "cp_trend",
+    typeDocxName: "cp_trend",
     typeFlag: "second",
     generalFiles: {
       urlType: "",
     },
     diagramRelations: {
-      urlType: "",
+      urlType: "boxMarkersCharts",
     },
   },
   {
@@ -181,6 +194,7 @@ export const allAnalysisType = [
     id: 114,
     parentId: 5,
     typeCode: "tsr",
+    typeDocxName: "tsr",
     typeFlag: "second",
     generalFiles: {
       urlType: "lineAndChildLine",
@@ -194,6 +208,7 @@ export const allAnalysisType = [
     id: 115,
     parentId: 5,
     typeCode: "tsr_windspeed",
+    typeDocxName: "tsr_windspeed",
     typeFlag: "second",
     generalFiles: {
       urlType: "lineAndChildLine",
@@ -207,12 +222,13 @@ export const allAnalysisType = [
     id: 116,
     parentId: 5,
     typeCode: "tsr_trend",
+    typeDocxName: "tsr_trend",
     typeFlag: "second",
     generalFiles: {
       urlType: "",
     },
     diagramRelations: {
-      urlType: "",
+      urlType: "boxMarkersCharts",
     },
   },
   {
@@ -220,6 +236,7 @@ export const allAnalysisType = [
     id: 117,
     parentId: 5,
     typeCode: "tsr_cp_power",
+    typeDocxName: "tsr_cp_power",
     typeFlag: "second",
     generalFiles: {
       urlType: "lineAndChildLine",
@@ -233,6 +250,7 @@ export const allAnalysisType = [
     id: 118,
     parentId: 5,
     typeCode: "tsr_cp_power_scatter",
+    typeDocxName: "tsr_cp_power_scatter",
     typeFlag: "second",
     generalFiles: {
       urlType: "TwoDMarkersChart",
@@ -246,6 +264,7 @@ export const allAnalysisType = [
     id: 127,
     parentId: 5,
     typeCode: "pitch_tsr_cp",
+    typeDocxName: "pitch_tsr_cp",
     typeFlag: "second",
     generalFiles: {
       urlType: "",
@@ -259,12 +278,13 @@ export const allAnalysisType = [
     id: 121,
     parentId: 6,
     typeCode: "yaw_error",
+    typeDocxName: "yaw_error",
     typeFlag: "second",
     generalFiles: {
-      urlType: "",
+      urlType: ["yawErrorBarSumChart", "yawErrorChart"],
     },
     diagramRelations: {
-      urlType: "",
+      urlType: "yawErrorLine",
     },
   },
   {
@@ -272,6 +292,7 @@ export const allAnalysisType = [
     id: 129,
     parentId: 6,
     typeCode: "yaw_error_density",
+    typeDocxName: "yaw_error_density",
     typeFlag: "second",
     generalFiles: {
       urlType: "",
@@ -286,6 +307,7 @@ export const allAnalysisType = [
     id: 122,
     parentId: 7,
     typeCode: "min_pitch",
+    typeDocxName: "min_pitch",
     typeFlag: "second",
     generalFiles: {
       urlType: "",
@@ -299,6 +321,7 @@ export const allAnalysisType = [
     id: 119,
     parentId: 8,
     typeCode: "speed_power",
+    typeDocxName: "speed_power",
     typeFlag: "minute",
     generalFiles: {
       urlType: "3DDrawingChart",
@@ -313,6 +336,7 @@ export const allAnalysisType = [
     id: 120,
     parentId: 8,
     typeCode: "speed_torque",
+    typeDocxName: "speed_torque",
     typeFlag: "minute",
     generalFiles: {
       urlType: "3DDrawingChart",
@@ -327,6 +351,7 @@ export const allAnalysisType = [
     id: 123,
     parentId: 8,
     typeCode: "pitch_power",
+    typeDocxName: "pitch_power",
     typeFlag: "minute",
     generalFiles: {
       urlType: "",
@@ -341,6 +366,7 @@ export const allAnalysisType = [
     id: 124,
     parentId: 8,
     typeCode: "pitch_generator_speed",
+    typeDocxName: "pitch_generator_speed",
     typeFlag: "minute",
     generalFiles: {
       urlType: "",
@@ -354,6 +380,7 @@ export const allAnalysisType = [
     id: 125,
     parentId: 9,
     typeCode: "temperature_environment",
+    typeDocxName: "temperature_environment",
     typeFlag: "minute",
     generalFiles: {
       urlType: "bar",
@@ -367,6 +394,7 @@ export const allAnalysisType = [
     id: 131,
     parentId: 9,
     typeCode: "temperature_large_components",
+    typeDocxName: "temperature_large_components_hig",
     typeFlag: "minute",
     filterFileAddr: "gearbox_high_speed_shaft_bearing_temperature",
     generalFiles: {
@@ -381,6 +409,7 @@ export const allAnalysisType = [
     id: 132,
     parentId: 9,
     typeCode: "temperature_large_components",
+    typeDocxName: "temperature_large_components_mid",
     typeFlag: "minute",
     filterFileAddr: "gearboxmedium_speed_shaftbearing_temperature",
     generalFiles: {
@@ -395,6 +424,7 @@ export const allAnalysisType = [
     id: 133,
     parentId: 9,
     typeCode: "temperature_large_components",
+    typeDocxName: "temperature_large_components_low",
     typeFlag: "minute",
     filterFileAddr: "gearbox_low_speed_shaft_bearing_temperature",
     generalFiles: {
@@ -409,8 +439,10 @@ export const allAnalysisType = [
     id: 134,
     parentId: 9,
     typeCode: "temperature_large_components",
+    typeDocxName: "temperature_large_components_min",
     typeFlag: "minute",
     filterFileAddr: "main_bearing_temperature",
+
     generalFiles: {
       urlType: "lineAndChildLine",
     },
@@ -423,6 +455,7 @@ export const allAnalysisType = [
     id: 135,
     parentId: 9,
     typeCode: "temperature_large_components",
+    typeDocxName: "temperature_large_components_adriven",
     typeFlag: "minute",
     filterFileAddr: "generatordrive_end_bearing_temperature",
     generalFiles: {
@@ -437,6 +470,7 @@ export const allAnalysisType = [
     id: 136,
     parentId: 9,
     typeCode: "temperature_large_components",
+    typeDocxName: "temperature_large_components_undriven",
     typeFlag: "minute",
     filterFileAddr: "generatornon_drive_end_bearing_temperature",
     generalFiles: {
@@ -451,6 +485,7 @@ export const allAnalysisType = [
     id: 137,
     parentId: 9,
     typeCode: "temperature_large_components",
+    typeDocxName: "temperature_large_components_tem_deviation",
     typeFlag: "minute",
     filterFileAddr: "GeneratorTemperature",
     generalFiles: {
@@ -465,6 +500,7 @@ export const allAnalysisType = [
     id: 138,
     parentId: 9,
     typeCode: "temperature_large_components",
+    typeDocxName: "temperature_large_components_Winding_tem",
     typeFlag: "minute",
     filterFileAddr: "generator_winding1_temperature",
     generalFiles: {
@@ -479,12 +515,14 @@ export const allAnalysisType = [
     id: 41,
     parentId: 10,
     typeCode: "production_indicator",
+    typeDocxName: "production_indicator_unit",
     typeFlag: "minute",
     generalFiles: {
-      urlType: "",
+      FileTypeFromUrl: "production_indicator_total",
+      urlType: "productionIndicatorTotal",
     },
     diagramRelations: {
-      urlType: "radar",
+      urlType: "",
     },
   },
   {
@@ -493,8 +531,10 @@ export const allAnalysisType = [
     parentId: 10,
     typeCode: "production_indicator",
     typeFlag: "minute",
+    typeDocxName: "production_indicator_all",
     generalFiles: {
-      urlType: "",
+      FileTypeFromUrl: "production_indicator_total",
+      urlType: "productionIndicatorTotal",
     },
     diagramRelations: {
       urlType: "",
@@ -506,8 +546,10 @@ export const allAnalysisType = [
     parentId: 11,
     typeCode: "fault",
     typeFlag: "fault",
+    typeDocxName: "fault_unit",
     generalFiles: {
-      urlType: "",
+      FileTypeFromUrl: "turbine_fault_result",
+      urlType: "faultUnitChart",
     },
     diagramRelations: {
       urlType: "",
@@ -518,9 +560,11 @@ export const allAnalysisType = [
     id: 130,
     parentId: 11,
     typeCode: "fault",
+    typeDocxName: "fault_all",
     typeFlag: "fault",
     generalFiles: {
-      urlType: "",
+      FileTypeFromUrl: "total_fault_result",
+      urlType: "faultAllChart",
     },
     diagramRelations: {
       urlType: "",

BIN
归档.zip


Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott