Преглед на файлове

添加额定功率折线图及3D散点图

liujiejie преди 4 месеца
родител
ревизия
37f6ff99e4
променени са 30 файла, в които са добавени 2103 реда и са изтрити 589 реда
  1. 2 2
      src/components/map/index.vue
  2. 72 0
      src/components/virtual_list/index.vue
  3. 8 2
      src/main.js
  4. 22 0
      src/mixins/chartRequestMixin.js
  5. 1 1
      src/utils/request.js
  6. 26 45
      src/views/overview/components/cp_trend/index.vue
  7. 20 43
      src/views/overview/components/min_pitch/index.vue
  8. 25 44
      src/views/overview/components/pitch_tsr_cp/index.vue
  9. 309 3
      src/views/overview/components/power_scatter/index.vue
  10. 20 42
      src/views/overview/components/power_scatter_2D/index.vue
  11. 25 46
      src/views/overview/components/rated_power_windspeed/index.vue
  12. 278 3
      src/views/overview/components/rated_windspeed/index.vue
  13. 293 3
      src/views/overview/components/temperature_environment/index.vue
  14. 293 3
      src/views/overview/components/tsr_cp_power/index.vue
  15. 26 44
      src/views/overview/components/tsr_cp_power_scatter/index.vue
  16. 25 43
      src/views/overview/components/tsr_trend/index.vue
  17. 20 13
      src/views/overview/components/wind_direction_frequency/index.vue
  18. 24 17
      src/views/overview/components/wind_speed/index.vue
  19. 27 5
      src/views/overview/components/wind_speed_frequency/index.vue
  20. 36 44
      src/views/overview/components/yaw_error_density/index.vue
  21. 222 0
      src/views/performance/components/chartsCom/3DDrawingChart.vue
  22. 28 7
      src/views/performance/components/chartsCom/BarChart.vue
  23. 17 4
      src/views/performance/components/chartsCom/BoxLineCharts.vue
  24. 17 3
      src/views/performance/components/chartsCom/BoxMarkersCharts.vue
  25. 19 44
      src/views/performance/components/chartsCom/NoColourBandTwoDMarkerChart.vue
  26. 51 48
      src/views/performance/components/chartsCom/TwoDMarkersChart.vue
  27. 17 5
      src/views/performance/components/chartsCom/WindRoseChart.vue
  28. 143 10
      src/views/performance/components/chartsCom/lineAndChildLine.vue
  29. 35 63
      src/views/performance/components/chartsCom/powerMarkers2DCharts.vue
  30. 2 2
      vue.config.js

+ 2 - 2
src/components/map/index.vue

@@ -196,8 +196,8 @@ export default {
         new TileLayer({
           source: new XYZ({
             // url: "http://127.0.0.1:8010/tiles/{z}/{x}/{y}.png", //本地
-            // url: "http://192.168.50.235/tiles/{z}/{x}/{y}.png", //内网
-            url: "http://106.120.102.238:18000/tiles/{z}/{x}/{y}.png", //外网
+            url: "http://192.168.50.235/tiles/{z}/{x}/{y}.png", //内网
+            // url: "http://106.120.102.238:18000/tiles/{z}/{x}/{y}.png", //外网
             // url: "http://10.96.137.5:9080/tiles/{z}/{x}/{y}.png", //大~#@唐
           }),
         }),

+ 72 - 0
src/components/virtual_list/index.vue

@@ -0,0 +1,72 @@
+<template>
+  <div class="virtual-list" :style="{ height: list.length === 0 || list.length === 1 ? '452px' : '' }">
+    <div class="charts" v-if="list && list.length > 0"
+      :style="{ height: list.length === 0 || list.length === 1 ? '452px' : '' }">
+      <!-- <RecycleScroller class="scroller" :items="diagramRelationsDatas" :item-size="452" key-field="fieldEngineCode"
+            v-slot="{ item: itemChart }">
+            <TwoDMarkersChart :key="itemChart.fieldEngineCode" :ref="itemChart.fieldEngineCode"
+              :fileAddr="itemChart.fileAddr">
+            </TwoDMarkersChart>
+          </RecycleScroller> -->
+      <!-- <template v-for="(itemChart, indChart) in diagramRelationsDatas">
+          
+          </template> -->
+      <RecycleScroller class="scroller" :items="list" :item-size="itemSize" :key-field="keyField"
+        v-slot="{ item, index }">
+        <slot :item="item" :index="index"></slot>
+      </RecycleScroller>
+    </div>
+    <el-empty description="暂无分析记录" v-else></el-empty>
+  </div>
+</template>
+
+<script type="text/javascript">
+//import HelloWorld from '@/components/HelloWorld.vue'
+export default {
+  name: "VirtualList",
+  components: {},
+  props: {
+    list: {
+      type: Array,
+      default: () => []
+    },
+    keyField: {
+      type: String,
+      default: 'id'
+    },
+    itemSize: {
+      type: Number,
+      default: 300
+    }
+  },
+  data() {
+    return {
+
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.charts {
+  height: calc(100% - 150px);
+}
+
+.virtual-list {
+  height: 100%;
+}
+
+.scroller {
+  height: 100%;
+
+  /* 隐藏垂直滚动条 */
+  &::-webkit-scrollbar {
+    width: 0;
+  }
+
+  /* 隐藏水平滚动条 */
+  &::-webkit-scrollbar {
+    height: 0;
+  }
+}
+</style>

+ 8 - 2
src/main.js

@@ -16,6 +16,9 @@ import "./styles/index.scss";
 import SvgIcons from "@/components/SvgIcons/index.vue";
 import VueDraggableResizable from "vue-draggable-resizable-gorkys";
 import "vue-draggable-resizable-gorkys/dist/VueDraggableResizable.css";
+import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
+import VirtualList from "@/components/virtual_list/index.vue";
+
 
 Vue.component("VueDraggableResizable", VueDraggableResizable);
 Vue.component("SvgIcons", SvgIcons);
@@ -27,6 +30,7 @@ import dataV from "@jiaminghi/data-view";
 import permission from "./directives/permission"; // 导入自定义指令
 import lazyLoad from "./directives/lazyLoad";
 import inview from "./directives/inview";
+
 import "echarts-gl";
 Vue.use(dataV);
 Vue.prototype.$qs = qs;
@@ -34,11 +38,13 @@ Vue.prototype.$qs = qs;
 
 // dialog拖拽全屏
 import dialogDrag from "./views/health/dialogDrag";
-import { RecycleScroller } from "vue-virtual-scroller";
+import { RecycleScroller } from 'vue-virtual-scroller'
 
 Vue.directive("dialogDrag", dialogDrag);
 
-Vue.component("RecycleScroller", RecycleScroller);
+Vue.component('RecycleScroller', RecycleScroller)
+Vue.component('VirtualList', VirtualList)
+
 Vue.use(ElementUI);
 // 引入tailwind
 // https://www.tailwindcss.cn/docs/installation

+ 22 - 0
src/mixins/chartRequestMixin.js

@@ -0,0 +1,22 @@
+// echarts 自适应父盒子变化大小
+const myMixin = {
+  data() {
+    return {
+    loading: false,
+    isError: false,
+    cancelToken: null
+   }
+  },
+  methods: {
+    cancelRequest() {
+      if (this.cancelToken) {
+        this.cancelToken.cancel('Request was cancelled');
+      }
+    },
+  },
+  beforeDestroy() {
+    this.cancelRequest()
+  }
+};
+
+export { myMixin };

+ 1 - 1
src/utils/request.js

@@ -20,8 +20,8 @@ service.interceptors.request.use(
         ?.token;
       if (token) {
         config.headers.token = token;
+        config.headers.showIp = "106.120.102.238";
       }
-      // config.headers.showIp = "http://106.120.102.238";
     }
     return config;
   },

+ 26 - 45
src/views/overview/components/cp_trend/index.vue

@@ -1,8 +1,8 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:06:09
- * @LastEditTime: 2025-01-17 18:01:52
- * @LastEditors: milo-MacBook-Pro.local
+ * @LastEditTime: 2025-01-20 09:21:51
+ * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/cp_trend/index.vue
 -->
@@ -34,21 +34,19 @@
           Cp的分析也是监测风机性能的重要手段。如果Cp值出现异常下降,可能预示着机械故障、叶片磨损或其他维护需求。
         </div>
       </el-alert>
-      <div class="charts" v-if="diagramRelationsDatas">
-        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
-          <BoxLineCharts
-            :key="itemChart.fieldEngineCode"
-            @getResult="getResult"
-            @changeRequestNum="changeRequestNum"
-            :result="requestResult"
-            :index="indChart"
-            :ref="itemChart.fieldEngineCode"
-            :fileAddr="itemChart.fileAddr"
-          >
-          </BoxLineCharts>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <BoxLineCharts
+          :key="item.fieldEngineCode + index"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        ></BoxLineCharts>
+      </VirtualList>
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -118,8 +116,6 @@ export default {
       options: [],
       generalFilesDatas: [], //总图
       diagramRelationsDatas: [], //分图,
-      requestResult: [], // 请求结果
-      requestRecord: [],
       commentDescriptionVos: [], //评论列表
       editableTabs: [],
     };
@@ -165,30 +161,6 @@ export default {
         this.loading = false;
       }
     },
-    getResult({ index, result }) {
-      console.log(index, result);
-      this.$set(this.requestResult, index, result);
-      // this.requestResult[index] = result
-      this.requestRecord[index] = result;
-    },
-    changeRequestNum(index) {
-      if (index <= 1) {
-        this.$set(this.requestRecord, index, "start");
-        return;
-      }
-      if (index > 1) {
-        if (
-          this.requestRecord.every((item) =>
-            ["success", "error"].includes(item)
-          )
-        ) {
-          this.$set(this.requestRecord, index, "start");
-          this.$set(this.requestResult, index, "start");
-        } else {
-          this.$set(this.requestRecord, index, "start");
-        }
-      }
-    },
     onSubmit() {
       console.log("submit!");
     },
@@ -236,9 +208,18 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
-          result.data && result.data[0] && result.data[0].diagramRelations;
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }

+ 20 - 43
src/views/overview/components/min_pitch/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:08:13
- * @LastEditTime: 2025-01-16 18:34:34
+ * @LastEditTime: 2025-01-20 09:22:11
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/min_pitch/index.vue
@@ -33,21 +33,19 @@
       </el-alert>
       <div></div>
       <div class="titleCharts">分析分图 :</div>
-      <div class="charts" v-if="diagramRelationsDatas">
-        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
-          <TwoDMarkersChart
-            :key="itemChart.fieldEngineCode"
-            @getResult="getResult"
-            @changeRequestNum="changeRequestNum"
-            :result="requestResult"
-            :index="indChart"
-            :ref="itemChart.fieldEngineCode"
-            :fileAddr="itemChart.fileAddr"
-          >
-          </TwoDMarkersChart>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <TwoDMarkersChart
+          :key="item.fieldEngineCode"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        ></TwoDMarkersChart>
+      </VirtualList>
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -121,8 +119,6 @@ export default {
       options: [],
       generalFilesDatas: [], //总图
       diagramRelationsDatas: [], //分图,
-      requestResult: [], // 请求结果
-      requestRecord: [],
       commentDescriptionVos: [], //评论列表
       editableTabs: [],
     };
@@ -168,30 +164,6 @@ export default {
         this.loading = false;
       }
     },
-    getResult({ index, result }) {
-      console.log(index, result);
-      this.$set(this.requestResult, index, result);
-      // this.requestResult[index] = result
-      this.requestRecord[index] = result;
-    },
-    changeRequestNum(index) {
-      if (index <= 1) {
-        this.$set(this.requestRecord, index, "start");
-        return;
-      }
-      if (index > 1) {
-        if (
-          this.requestRecord.every((item) =>
-            ["success", "error"].includes(item)
-          )
-        ) {
-          this.$set(this.requestRecord, index, "start");
-          this.$set(this.requestResult, index, "start");
-        } else {
-          this.$set(this.requestRecord, index, "start");
-        }
-      }
-    },
     onSubmit() {
       console.log("submit!");
     },
@@ -239,7 +211,12 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
           result.data &&
           result.data[0] &&

+ 25 - 44
src/views/overview/components/pitch_tsr_cp/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:09:55
- * @LastEditTime: 2025-01-16 16:12:31
+ * @LastEditTime: 2025-01-20 09:19:16
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/pitch_tsr_cp/index.vue
@@ -31,21 +31,19 @@
           风能利用系数可以表示为变桨角度和叶尖速比的函数。每一个确定的桨距角,都存在一个最大风力利用系数,随着桨距角的变大,最大风力利用系数降低,其对应的叶尖速比也降低。此分析可以看出机组的发电情况表现。
         </div>
       </el-alert>
-      <div class="charts" v-if="diagramRelationsDatas">
-        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
-          <TwoDMarkersChart
-            :key="itemChart.fieldEngineCode"
-            @getResult="getResult"
-            @changeRequestNum="changeRequestNum"
-            :result="requestResult"
-            :index="indChart"
-            :ref="itemChart.fieldEngineCode"
-            :fileAddr="itemChart.fileAddr"
-          >
-          </TwoDMarkersChart>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <TwoDMarkersChart
+          :key="item.fieldEngineCode + index"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        ></TwoDMarkersChart>
+      </VirtualList>
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -115,8 +113,6 @@ export default {
       options: [],
       generalFilesDatas: [], //总图
       diagramRelationsDatas: [], //分图,
-      requestResult: [], // 请求结果
-      requestRecord: [],
       commentDescriptionVos: [], //评论列表
       editableTabs: [],
     };
@@ -162,30 +158,6 @@ export default {
         this.loading = false;
       }
     },
-    getResult({ index, result }) {
-      console.log(index, result);
-      this.$set(this.requestResult, index, result);
-      // this.requestResult[index] = result
-      this.requestRecord[index] = result;
-    },
-    changeRequestNum(index) {
-      if (index <= 1) {
-        this.$set(this.requestRecord, index, "start");
-        return;
-      }
-      if (index > 1) {
-        if (
-          this.requestRecord.every((item) =>
-            ["success", "error"].includes(item)
-          )
-        ) {
-          this.$set(this.requestRecord, index, "start");
-          this.$set(this.requestResult, index, "start");
-        } else {
-          this.$set(this.requestRecord, index, "start");
-        }
-      }
-    },
     onSubmit() {
       console.log("submit!");
     },
@@ -233,9 +205,18 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
-          result.data && result.data[0] && result.data[0].diagramRelations;
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }

+ 309 - 3
src/views/overview/components/power_scatter/index.vue

@@ -1,17 +1,323 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:10:22
- * @LastEditTime: 2025-01-10 09:17:58
+ * @LastEditTime: 2025-01-20 09:28:43
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/power_scatter/index.vue
 -->
+
 <template>
-  <div>逐月有功功率散点3D分析</div>
+  <div class="type-variable">
+    <!-- 逐月有功功率散点3D分析--只有分图不存在总图 -->
+    <div class="left">
+      <FilterChart
+        :windList="windEngineGroupList"
+        @getEnfineList="getEnfineList"
+        @handlePrevious="handlePrevious"
+        @handleNext="handleNext"
+      ></FilterChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          动态偏航误差分析是对机组偏航对风角度的分布情况进行统计及可视化展示,对风角度分布对称性较差的机组需要关注其偏航系统对风异常原因。
+        </div>
+      </el-alert>
+      <div class="titleCharts">分析分图 :</div>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <DDrawingChart
+          :key="item.fieldEngineCode"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </DDrawingChart>
+      </VirtualList>
+
+      <el-tabs value="first">
+        <el-tab-pane label="意见描述" name="first">
+          <TinymceEditor
+            ref="editor"
+            v-model="comment"
+            @input="handleEditorInput($event)"
+            @onClick="onClick"
+          >
+          </TinymceEditor>
+        </el-tab-pane>
+      </el-tabs>
+      <el-row type="flex" class="row-bg" justify="end">
+        <el-col :span="2" style="margin: 20px">
+          <el-button type="primary" size="small" @click="handleComment"
+            >提交评论</el-button
+          >
+        </el-col>
+      </el-row>
+    </div>
+    <div class="right">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
 <script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import DDrawingChart from "@/views/performance/components/chartsCom/3DDrawingChart.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "powerScatter",
+  components: {
+    DicCard,
+    FilterChart,
+    DDrawingChart,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图,
+      requestResult: [], // 请求结果
+      requestRecord: [],
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+    };
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    getResult({ index, result }) {
+      console.log(index, result);
+      this.$set(this.requestResult, index, result);
+      // this.requestResult[index] = result
+      this.requestRecord[index] = result;
+    },
+    changeRequestNum(index) {
+      if (index <= 1) {
+        this.$set(this.requestRecord, index, "start");
+        return;
+      }
+      if (index > 1) {
+        if (
+          this.requestRecord.every((item) =>
+            ["success", "error"].includes(item)
+          )
+        ) {
+          this.$set(this.requestRecord, index, "start");
+          this.$set(this.requestResult, index, "start");
+        } else {
+          this.$set(this.requestRecord, index, "start");
+        }
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        console.log(
+          this.initBatchCode,
+          this.analysisTypeCode,
+          "请求详情 分钟级"
+        );
+        // 获取分析详情
+        await this.getAnalysisDetail();
+
+        // 获取风机列表
+        await this.getWindEnfineList(this.initBatchCode, this.analysisTypeCode);
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
+        this.generalFilesDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
+        this.diagramRelationsDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
+      } catch (err) {
+        console.error("Failed to fetch analysis details:", err);
+      }
+    },
+
+    // 请求风机列表
+    async getWindEnfineList(batchCode, analysisTypeCode) {
+      // console.log("请求风机列表 分钟级");
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: batchCode,
+        analysisTypeCode,
+      });
+      this.windEngineGroupList = resEngineList.data;
+    },
+    handleEditorInput(index, newVal) {
+      // 更新对应的 comment 值
+      // 如果该功能没有实现,可以删除这个方法
+    },
+    //获取选中风机list
+    getEnfineList(data) {
+      this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
+    },
+    //下一条
+    handleNext() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === this.batchCodeList.length - 1) {
+        this.$message.warning("已经是最后一个分析结果了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index + 1]);
+    },
+    //上一条
+    handlePrevious() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === 0) {
+        this.$message.warning("没有上一条了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index - 1]);
+    },
+    onClick() {},
+  },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px;
+    flex: 1;
+  }
+
+  .right {
+    width: 250px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 20 - 42
src/views/overview/components/power_scatter_2D/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:10:35
- * @LastEditTime: 2025-01-17 11:32:49
+ * @LastEditTime: 2025-01-20 09:22:44
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/power_scatter_2D/index.vue
@@ -40,20 +40,19 @@ export default {
         </div>
       </el-alert>
       <div class="titleCharts">分析分图 :</div>
-      <div class="charts" v-if="diagramRelationsDatas">
-        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
-          <powerMarkers2DCharts
-            :key="itemChart.fieldEngineCode + indChart"
-            :index="indChart"
-            @getResult="getResult"
-            @changeRequestNum="changeRequestNum"
-            :result="requestResult"
-            :ref="itemChart.fieldEngineCode"
-            :fileAddr="itemChart.fileAddr"
-          ></powerMarkers2DCharts>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <powerMarkers2DCharts
+          :key="item.fieldEngineCode + index"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        ></powerMarkers2DCharts>
+      </VirtualList>
 
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
@@ -127,8 +126,6 @@ export default {
       diagramRelationsDatas: [], //分图
       commentDescriptionVos: [], //评论列表
       editableTabs: [],
-      requestResult: [], // 请求结果
-      requestRecord: [],
     };
   },
   watch: {
@@ -149,12 +146,6 @@ export default {
     }
   },
   methods: {
-    getResult({ index, result }) {
-      console.log(index, result);
-      this.$set(this.requestResult, index, result);
-      // this.requestResult[index] = result
-      this.requestRecord[index] = result;
-    },
     // 请求风机列表
     async getWindEnfineList(batchCode, analysisTypeCode) {
       // console.log("请求风机列表 分钟级");
@@ -164,24 +155,6 @@ export default {
       });
       this.windEngineGroupList = resEngineList.data;
     },
-    changeRequestNum(index) {
-      if (index <= 1) {
-        this.$set(this.requestRecord, index, "start");
-        return;
-      }
-      if (index > 1) {
-        if (
-          this.requestRecord.every((item) =>
-            ["success", "error"].includes(item)
-          )
-        ) {
-          this.$set(this.requestRecord, index, "start");
-          this.$set(this.requestResult, index, "start");
-        } else {
-          this.$set(this.requestRecord, index, "start");
-        }
-      }
-    },
     async handleComment() {
       try {
         await analysisCommentEdit({
@@ -252,7 +225,12 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
           result.data &&
           result.data[0] &&

+ 25 - 46
src/views/overview/components/rated_power_windspeed/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:10:47
- * @LastEditTime: 2025-01-17 09:25:18
+ * @LastEditTime: 2025-01-20 09:19:28
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/rated_power_windspeed/index.vue
@@ -32,24 +32,20 @@
         </div>
       </el-alert>
       <div class="titleCharts">分析总图 :</div>
-      <div
-        class="charts"
-        v-if="generalFilesDatas && generalFilesDatas.length > 0"
+      <VirtualList
+        :list="generalFilesDatas"
+        keyField="batchCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
       >
-        <template v-for="(itemChart, indChart) in generalFilesDatas">
-          <BoxLineCharts
-            :key="itemChart.batchCode + indChart"
-            @getResult="getResult"
-            @changeRequestNum="changeRequestNum"
-            :result="requestResult"
-            :index="indChart"
-            :ref="itemChart.batchCode + indChart"
-            :fileAddr="itemChart.fileAddr"
-          >
-          </BoxLineCharts>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+        <BoxLineCharts
+          :key="item.batchCode + index"
+          :index="index"
+          :ref="item.batchCode + indChart"
+          :fileAddr="item.fileAddr"
+        >
+        </BoxLineCharts>
+      </VirtualList>
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -120,8 +116,6 @@ export default {
       options: [],
       generalFilesDatas: [], //总图
       diagramRelationsDatas: [], //分图,
-      requestResult: [], // 请求结果
-      requestRecord: [],
       commentDescriptionVos: [], //评论列表
       editableTabs: [],
     };
@@ -167,30 +161,6 @@ export default {
         this.loading = false;
       }
     },
-    getResult({ index, result }) {
-      console.log(index, result);
-      this.$set(this.requestResult, index, result);
-      // this.requestResult[index] = result
-      this.requestRecord[index] = result;
-    },
-    changeRequestNum(index) {
-      if (index <= 1) {
-        this.$set(this.requestRecord, index, "start");
-        return;
-      }
-      if (index > 1) {
-        if (
-          this.requestRecord.every((item) =>
-            ["success", "error"].includes(item)
-          )
-        ) {
-          this.$set(this.requestRecord, index, "start");
-          this.$set(this.requestResult, index, "start");
-        } else {
-          this.$set(this.requestRecord, index, "start");
-        }
-      }
-    },
     onSubmit() {
       console.log("submit!");
     },
@@ -238,9 +208,18 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
-          result.data && result.data[0] && result.data[0].diagramRelations;
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }

+ 278 - 3
src/views/overview/components/rated_windspeed/index.vue

@@ -1,17 +1,292 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:08:56
- * @LastEditTime: 2025-01-10 09:17:01
+ * @LastEditTime: 2025-01-20 09:23:01
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/rated_windspeed/index.vue
 -->
+
 <template>
-  <div>额定风速分析</div>
+  <div class="type-variable">
+    <!-- 额定风速分析 -->
+    <div class="left">
+      <FilterChart
+        :windList="windEngineGroupList"
+        @getEnfineList="getEnfineList"
+        @handlePrevious="handlePrevious"
+        @handleNext="handleNext"
+      ></FilterChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          风向玫瑰图是一种表示某地不同风向出现频率分布的图表。
+        </div>
+      </el-alert>
+
+      <div class="titleCharts">分析总图 :</div>
+      <VirtualList
+        :list="generalFilesDatas"
+        keyField="batchCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <BarChart
+          :key="item.batchCode + index"
+          :inds="index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        >
+        </BarChart>
+      </VirtualList>
+      <el-tabs value="first">
+        <el-tab-pane label="意见描述" name="first">
+          <TinymceEditor
+            ref="editor"
+            v-model="comment"
+            @input="handleEditorInput($event)"
+            @onClick="onClick"
+          >
+          </TinymceEditor>
+        </el-tab-pane>
+      </el-tabs>
+      <el-row type="flex" class="row-bg" justify="end">
+        <el-col :span="2" style="margin: 20px">
+          <el-button type="primary" size="small" @click="handleComment"
+            >提交评论</el-button
+          >
+        </el-col>
+      </el-row>
+    </div>
+    <div class="right">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
 <script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import BarChart from "@/views/performance/components/chartsCom/BarChart.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "ratedWindspeed",
+  components: {
+    DicCard,
+    FilterChart,
+    BarChart,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      comment: "",
+      options: [],
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+    };
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        // 获取分析详情
+        await this.getAnalysisDetail();
+        // 获取风机列表
+        await this.getWindEnfineList(this.initBatchCode, this.analysisTypeCode);
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
+        this.generalFilesDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
+        this.diagramRelationsDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
+      } catch (err) {
+        console.error("Failed to fetch analysis details:", err);
+      }
+    },
+
+    // 请求风机列表
+    async getWindEnfineList(batchCode, analysisTypeCode) {
+      // console.log("请求风机列表 分钟级");
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: batchCode,
+        analysisTypeCode,
+      });
+      this.windEngineGroupList = resEngineList.data;
+    },
+    handleEditorInput(index, newVal) {
+      // 更新对应的 comment 值
+      // 如果该功能没有实现,可以删除这个方法
+    },
+    //获取选中风机list
+    getEnfineList(data) {
+      this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
+    },
+    //下一条
+    handleNext() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === this.batchCodeList.length - 1) {
+        this.$message.warning("已经是最后一个分析结果了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index + 1]);
+    },
+    //上一条
+    handlePrevious() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === 0) {
+        this.$message.warning("没有上一条了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index - 1]);
+    },
+    onClick() {},
+  },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px;
+    flex: 1;
+  }
+
+  .right {
+    width: 250px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 293 - 3
src/views/overview/components/temperature_environment/index.vue

@@ -1,17 +1,307 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:09:46
- * @LastEditTime: 2025-01-10 09:15:43
+ * @LastEditTime: 2025-01-20 09:19:35
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/temperature_environment/index.vue
 -->
+
 <template>
-  <div>环境温度传感器分析</div>
+  <div class="type-variable">
+    <!-- 环境温度传感器分析 -->
+    <div class="left">
+      <FilterChart
+        :windList="windEngineGroupList"
+        @getEnfineList="getEnfineList"
+        @handlePrevious="handlePrevious"
+        @handleNext="handleNext"
+      ></FilterChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          风向玫瑰图是一种表示某地不同风向出现频率分布的图表。
+        </div>
+      </el-alert>
+
+      <div class="titleCharts">分析总图 :</div>
+      <VirtualList
+        :list="generalFilesDatas"
+        keyField="batchCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <BarChart
+          :key="item.batchCode + index"
+          :inds="index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        >
+        </BarChart>
+      </VirtualList>
+      <div class="titleCharts">分析分图 :</div>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <BarChart
+          :key="item.fieldEngineCode + index"
+          :inds="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </BarChart>
+      </VirtualList>
+      <el-tabs value="first">
+        <el-tab-pane label="意见描述" name="first">
+          <TinymceEditor
+            ref="editor"
+            v-model="comment"
+            @input="handleEditorInput($event)"
+            @onClick="onClick"
+          >
+          </TinymceEditor>
+        </el-tab-pane>
+      </el-tabs>
+      <el-row type="flex" class="row-bg" justify="end">
+        <el-col :span="2" style="margin: 20px">
+          <el-button type="primary" size="small" @click="handleComment"
+            >提交评论</el-button
+          >
+        </el-col>
+      </el-row>
+    </div>
+    <div class="right">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
 <script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import BarChart from "@/views/performance/components/chartsCom/BarChart.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "temperatureEnvironment",
+  components: {
+    DicCard,
+    FilterChart,
+    BarChart,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      comment: "",
+      options: [],
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+    };
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        // 获取分析详情
+        await this.getAnalysisDetail();
+        // 获取风机列表
+        await this.getWindEnfineList(this.initBatchCode, this.analysisTypeCode);
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
+        this.generalFilesDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
+        this.diagramRelationsDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
+      } catch (err) {
+        console.error("Failed to fetch analysis details:", err);
+      }
+    },
+
+    // 请求风机列表
+    async getWindEnfineList(batchCode, analysisTypeCode) {
+      // console.log("请求风机列表 分钟级");
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: batchCode,
+        analysisTypeCode,
+      });
+      this.windEngineGroupList = resEngineList.data;
+    },
+    handleEditorInput(index, newVal) {
+      // 更新对应的 comment 值
+      // 如果该功能没有实现,可以删除这个方法
+    },
+    //获取选中风机list
+    getEnfineList(data) {
+      this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
+    },
+    //下一条
+    handleNext() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === this.batchCodeList.length - 1) {
+        this.$message.warning("已经是最后一个分析结果了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index + 1]);
+    },
+    //上一条
+    handlePrevious() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === 0) {
+        this.$message.warning("没有上一条了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index - 1]);
+    },
+    onClick() {},
+  },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px;
+    flex: 1;
+  }
+
+  .right {
+    width: 250px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 293 - 3
src/views/overview/components/tsr_cp_power/index.vue

@@ -1,17 +1,307 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:10:24
- * @LastEditTime: 2025-01-10 09:15:01
+ * @LastEditTime: 2025-01-20 09:23:09
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/tsr_cp_power/index.vue
 -->
+
 <template>
-  <div>叶尖速比-风能利用系数-功率分析</div>
+  <div class="type-variable">
+    <!-- 叶尖速比-风能利用系数-功率分析 -->
+    <div class="left">
+      <FilterChart
+        :windList="windEngineGroupList"
+        @getEnfineList="getEnfineList"
+        @handlePrevious="handlePrevious"
+        @handleNext="handleNext"
+      ></FilterChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          风向玫瑰图是一种表示某地不同风向出现频率分布的图表。
+        </div>
+      </el-alert>
+
+      <div class="titleCharts">分析总图 :</div>
+      <VirtualList
+        :list="generalFilesDatas"
+        keyField="batchCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <lineAndChildLine
+          :key="item.batchCode + index"
+          :inds="index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineAndChildLine>
+      </VirtualList>
+      <div class="titleCharts">分析分图 :</div>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <lineAndChildLine
+          :key="item.fieldEngineCode + index"
+          :inds="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineAndChildLine>
+      </VirtualList>
+      <el-tabs value="first">
+        <el-tab-pane label="意见描述" name="first">
+          <TinymceEditor
+            ref="editor"
+            v-model="comment"
+            @input="handleEditorInput($event)"
+            @onClick="onClick"
+          >
+          </TinymceEditor>
+        </el-tab-pane>
+      </el-tabs>
+      <el-row type="flex" class="row-bg" justify="end">
+        <el-col :span="2" style="margin: 20px">
+          <el-button type="primary" size="small" @click="handleComment"
+            >提交评论</el-button
+          >
+        </el-col>
+      </el-row>
+    </div>
+    <div class="right">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
 <script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import lineAndChildLine from "@/views/performance/components/chartsCom/lineAndChildLine.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "tsrCpPower",
+  components: {
+    DicCard,
+    FilterChart,
+    lineAndChildLine,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      comment: "",
+      options: [],
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+    };
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        // 获取分析详情
+        await this.getAnalysisDetail();
+        // 获取风机列表
+        await this.getWindEnfineList(this.initBatchCode, this.analysisTypeCode);
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
+        this.generalFilesDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
+        this.diagramRelationsDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
+      } catch (err) {
+        console.error("Failed to fetch analysis details:", err);
+      }
+    },
+
+    // 请求风机列表
+    async getWindEnfineList(batchCode, analysisTypeCode) {
+      // console.log("请求风机列表 分钟级");
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: batchCode,
+        analysisTypeCode,
+      });
+      this.windEngineGroupList = resEngineList.data;
+    },
+    handleEditorInput(index, newVal) {
+      // 更新对应的 comment 值
+      // 如果该功能没有实现,可以删除这个方法
+    },
+    //获取选中风机list
+    getEnfineList(data) {
+      this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
+    },
+    //下一条
+    handleNext() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === this.batchCodeList.length - 1) {
+        this.$message.warning("已经是最后一个分析结果了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index + 1]);
+    },
+    //上一条
+    handlePrevious() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === 0) {
+        this.$message.warning("没有上一条了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index - 1]);
+    },
+    onClick() {},
+  },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px;
+    flex: 1;
+  }
+
+  .right {
+    width: 250px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 26 - 44
src/views/overview/components/tsr_cp_power_scatter/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:22:59
- * @LastEditTime: 2025-01-17 17:26:48
+ * @LastEditTime: 2025-01-20 09:19:44
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/index.vue
@@ -31,21 +31,20 @@
           动态偏航误差分析是对机组偏航对风角度的分布情况进行统计及可视化展示,对风角度分布对称性较差的机组需要关注其偏航系统对风异常原因。
         </div>
       </el-alert>
-      <div class="charts" v-if="diagramRelationsDatas">
-        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
-          <NoColourBandTwoDMarkerChart
-            :key="itemChart.fieldEngineCode"
-            @getResult="getResult"
-            @changeRequestNum="changeRequestNum"
-            :result="requestResult"
-            :index="indChart"
-            :ref="itemChart.fieldEngineCode"
-            :fileAddr="itemChart.fileAddr"
-          >
-          </NoColourBandTwoDMarkerChart>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <NoColourBandTwoDMarkerChart
+          :key="item.fieldEngineCode"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </NoColourBandTwoDMarkerChart>
+      </VirtualList>
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -115,8 +114,6 @@ export default {
       options: [],
       generalFilesDatas: [], //总图
       diagramRelationsDatas: [], //分图,
-      requestResult: [], // 请求结果
-      requestRecord: [],
       commentDescriptionVos: [], //评论列表
       editableTabs: [],
     };
@@ -162,30 +159,6 @@ export default {
         this.loading = false;
       }
     },
-    getResult({ index, result }) {
-      console.log(index, result);
-      this.$set(this.requestResult, index, result);
-      // this.requestResult[index] = result
-      this.requestRecord[index] = result;
-    },
-    changeRequestNum(index) {
-      if (index <= 1) {
-        this.$set(this.requestRecord, index, "start");
-        return;
-      }
-      if (index > 1) {
-        if (
-          this.requestRecord.every((item) =>
-            ["success", "error"].includes(item)
-          )
-        ) {
-          this.$set(this.requestRecord, index, "start");
-          this.$set(this.requestResult, index, "start");
-        } else {
-          this.$set(this.requestRecord, index, "start");
-        }
-      }
-    },
     onSubmit() {
       console.log("submit!");
     },
@@ -233,9 +206,18 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
-          result.data && result.data[0] && result.data[0].diagramRelations;
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }

+ 25 - 43
src/views/overview/components/tsr_trend/index.vue

@@ -34,21 +34,20 @@
           Cp的分析也是监测风机性能的重要手段。如果Cp值出现异常下降,可能预示着机械故障、叶片磨损或其他维护需求。
         </div>
       </el-alert>
-      <div class="charts" v-if="diagramRelationsDatas">
-        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
-          <BoxMarkersCharts
-            :key="itemChart.fieldEngineCode"
-            @getResult="getResult"
-            @changeRequestNum="changeRequestNum"
-            :result="requestResult"
-            :index="indChart"
-            :ref="itemChart.fieldEngineCode"
-            :fileAddr="itemChart.fileAddr"
-          >
-          </BoxMarkersCharts>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <BoxMarkersCharts
+          :key="item.fieldEngineCode"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </BoxMarkersCharts>
+      </VirtualList>
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -119,8 +118,6 @@ export default {
       options: [],
       generalFilesDatas: [], //总图
       diagramRelationsDatas: [], //分图,
-      requestResult: [], // 请求结果
-      requestRecord: [],
       commentDescriptionVos: [], //评论列表
       editableTabs: [],
     };
@@ -166,30 +163,6 @@ export default {
         this.loading = false;
       }
     },
-    getResult({ index, result }) {
-      console.log(index, result);
-      this.$set(this.requestResult, index, result);
-      // this.requestResult[index] = result
-      this.requestRecord[index] = result;
-    },
-    changeRequestNum(index) {
-      if (index <= 1) {
-        this.$set(this.requestRecord, index, "start");
-        return;
-      }
-      if (index > 1) {
-        if (
-          this.requestRecord.every((item) =>
-            ["success", "error"].includes(item)
-          )
-        ) {
-          this.$set(this.requestRecord, index, "start");
-          this.$set(this.requestResult, index, "start");
-        } else {
-          this.$set(this.requestRecord, index, "start");
-        }
-      }
-    },
     onSubmit() {
       console.log("submit!");
     },
@@ -237,9 +210,18 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
-          result.data && result.data[0] && result.data[0].diagramRelations;
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }

+ 20 - 13
src/views/overview/components/wind_direction_frequency/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:11:12
- * @LastEditTime: 2025-01-17 16:21:27
+ * @LastEditTime: 2025-01-20 09:23:19
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/wind_direction_frequency/index.vue
@@ -31,17 +31,19 @@
         </div>
       </el-alert>
       <div class="titleCharts">分析分图 :</div>
-      <div class="charts" v-if="diagramRelationsDatas">
-        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
-          <WindRoseChart
-            :key="itemChart.fieldEngineCode + indChart"
-            :inds="indChart"
-            :ref="itemChart.fieldEngineCode"
-            :fileAddr="itemChart.fileAddr"
-          ></WindRoseChart>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <WindRoseChart
+          :key="item.fieldEngineCode + index"
+          :inds="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        ></WindRoseChart>
+      </VirtualList>
 
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
@@ -205,7 +207,12 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
           result.data &&
           result.data[0] &&

+ 24 - 17
src/views/overview/components/wind_speed/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:11:23
- * @LastEditTime: 2025-01-17 16:57:43
+ * @LastEditTime: 2025-01-20 09:19:52
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/wind_spee/index.vue
@@ -33,21 +33,19 @@
       </el-alert>
 
       <div class="titleCharts">分析总图 :</div>
-      <div
-        class="charts"
-        v-if="generalFilesDatas && generalFilesDatas.length > 0"
+      <VirtualList
+        :list="generalFilesDatas"
+        keyField="batchCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
       >
-        <template v-for="(itemChart, indChart) in generalFilesDatas">
-          <BarChart
-            :key="itemChart.batchCode + indChart"
-            :inds="indChart"
-            :ref="itemChart.batchCode"
-            :fileAddr="itemChart.fileAddr"
-          ></BarChart>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
-
+        <BarChart
+          :key="item.batchCode + index"
+          :inds="index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        ></BarChart>
+      </VirtualList>
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -203,9 +201,18 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
-          result.data && result.data[0] && result.data[0].diagramRelations;
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }

+ 27 - 5
src/views/overview/components/wind_speed_frequency/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:11:34
- * @LastEditTime: 2025-01-17 17:19:47
+ * @LastEditTime: 2025-01-20 09:21:34
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/wind_speed_frequency/index.vue
@@ -31,7 +31,20 @@
         </div>
       </el-alert>
       <div class="titleCharts">分析分图 :</div>
-      <div
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <BarChart
+          :key="item.fieldEngineCode + index"
+          :inds="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        ></BarChart>
+      </VirtualList>
+      <!-- <div
         class="charts"
         v-if="diagramRelationsDatas && diagramRelationsDatas.length > 0"
       >
@@ -44,7 +57,7 @@
           ></BarChart>
         </template>
       </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+      <el-empty description="暂无分析记录" v-else></el-empty> -->
 
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
@@ -201,9 +214,18 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
-          result.data && result.data[0] && result.data[0].diagramRelations;
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }

+ 36 - 44
src/views/overview/components/yaw_error_density/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:26:12
- * @LastEditTime: 2025-01-17 10:51:47
+ * @LastEditTime: 2025-01-20 09:23:35
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/yaw_error_density/index.vue
@@ -27,24 +27,30 @@
           </div>
         </template>
         <div style="font-size: 12px; margin-top: 10px">
-          动态偏航误差分析是对机组偏航对风角度的分布情况进行统计及可视化展示,对风角度分布对称性较差的机组需要关注其偏航系统对风异常原因
+          风能利用系数可以表示为变桨角度和叶尖速比的函数。每一个确定的桨距角,都存在一个最大风力利用系数,随着桨距角的变大,最大风力利用系数降低,其对应的叶尖速比也降低。此分析可以看出机组的发电情况表现
         </div>
       </el-alert>
-      <div class="charts" v-if="diagramRelationsDatas">
-        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
-          <TwoDMarkersChart
-            :key="itemChart.fieldEngineCode"
-            @getResult="getResult"
-            @changeRequestNum="changeRequestNum"
-            :result="requestResult"
-            :index="indChart"
-            :ref="itemChart.fieldEngineCode"
-            :fileAddr="itemChart.fileAddr"
-          >
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item }"
+      >
+        <TwoDMarkersChart
+          :key="item.fieldEngineCode"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </TwoDMarkersChart>
+      </VirtualList>
+      <!-- <div class="charts" v-if="diagramRelationsDatas">
+        <RecycleScroller class="scroller" :items="diagramRelationsDatas" :item-size="452" 
+          v-slot="{ item: itemChart }">
+          <TwoDMarkersChart :key="itemChart.fieldEngineCode" :ref="itemChart.fieldEngineCode"
+            :fileAddr="itemChart.fileAddr">
           </TwoDMarkersChart>
-        </template>
-      </div>
-      <el-empty description="暂无分析记录" v-else></el-empty>
+        </RecycleScroller>
+      </div> -->
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -80,7 +86,6 @@ import FilterChart from "@/views/overview/components/filterChart/index.vue";
 import TwoDMarkersChart from "@/views/performance/components/chartsCom/TwoDMarkersChart.vue";
 import TinymceEditor from "@/components/Tinymce.vue";
 import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
-
 export default {
   name: "yaw_error_density",
   components: {
@@ -161,30 +166,6 @@ export default {
         this.loading = false;
       }
     },
-    getResult({ index, result }) {
-      console.log(index, result);
-      this.$set(this.requestResult, index, result);
-      // this.requestResult[index] = result
-      this.requestRecord[index] = result;
-    },
-    changeRequestNum(index) {
-      if (index <= 1) {
-        this.$set(this.requestRecord, index, "start");
-        return;
-      }
-      if (index > 1) {
-        if (
-          this.requestRecord.every((item) =>
-            ["success", "error"].includes(item)
-          )
-        ) {
-          this.$set(this.requestRecord, index, "start");
-          this.$set(this.requestResult, index, "start");
-        } else {
-          this.$set(this.requestRecord, index, "start");
-        }
-      }
-    },
     onSubmit() {
       console.log("submit!");
     },
@@ -214,7 +195,7 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes.join(","),
+              : this.fieldEngineCodes,
         });
         if (
           result.data &&
@@ -223,6 +204,7 @@ export default {
         ) {
           this.editableTabs = result.data[0].commentTypeRelations;
         }
+
         //当前评论展示获取
         if (
           result.data &&
@@ -232,9 +214,18 @@ export default {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
         this.generalFilesDatas =
-          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
         this.diagramRelationsDatas =
-          result.data && result.data[0] && result.data[0].diagramRelations;
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }
@@ -256,6 +247,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
+      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
       this.getAnalysisDetail();
     },
     //下一条

+ 222 - 0
src/views/performance/components/chartsCom/3DDrawingChart.vue

@@ -0,0 +1,222 @@
+<!--
+ * @Author: your name
+ * @Date: 2025-01-17 19:04:52
+ * @LastEditTime: 2025-01-20 09:37:15
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/chartsCom/3DDrawingChart.vue
+-->
+<template>
+  <div
+    :id="`plotly-3d-chart-` + index"
+    style="width: 100%; height: 400px"
+  ></div>
+</template>
+
+<script>
+import Plotly from "plotly.js-dist";
+import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin";
+export default {
+  props: {
+    fileAddr: {
+      default: "",
+      type: String,
+    },
+    index: {
+      default: "",
+      type: Number,
+    },
+  },
+  data() {
+    return {
+      color1: "",
+      chartData: {
+        // analysisTypeCode: "发电机转速和有功功率分析",
+        // engineCode: "WEM00013",
+        // engineTypeName: "WT2000/100",
+        // xaixs: "发电机转速(r/min)",
+        // yaixs: "时间",
+        // zaixs: "有功功率(kw)",
+        // data: [
+        //   {
+        //     engineName: "#01",
+        //     engineCode: "WOG00604",
+        //     title: " 月度发电机转速功率3D散点图:#01",
+        //     xData: [
+        //       1079.0, 1080.0, 1796.0, 1798.0, 1800.0, 1800.0, 1797.0, 1799.0,
+        //       1782.0, 1637.0, 1680.0, 1536.0, 1560.0, 1545.0, 1699.0, 1686.0,
+        //       1700.0, 1711.0, 1605.0, 1277.0, 1182.0, 1171.0, 1080.0, 1080.0,
+        //       1080.0, 1079.0, 1079.0, 1080.0, 1097.0, 1165.0, 1080.0, 1080.0,
+        //       1080.0, 1080.0, 1122.0, 1079.0, 1079.0, 1079.0, 1296.0,
+        //     ],
+        //     yData: [
+        //       "2023-01",
+        //       "2023-01",
+        //       "2023-01",
+        //       "2023-01",
+        //       "2023-01",
+        //       "2023-01",
+        //       "2023-01",
+        //       "2023-01",
+        //       "2023-10",
+        //       "2023-10",
+        //       "2023-10",
+        //       "2023-10",
+        //       "2023-10",
+        //       "2023-10",
+        //       "2023-10",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //       "2023-11",
+        //     ],
+        //     zData: [
+        //       100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200,
+        //       1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300,
+        //       2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400,
+        //     ],
+        //     mode: "markers",
+        //   },
+        // ],
+      },
+    };
+  },
+  mixins: [myMixin],
+  async mounted() {
+    this.getData();
+  },
+
+  methods: {
+    async getData() {
+      if (this.fileAddr !== "") {
+        try {
+          this.loading = true;
+          this.cancelToken = axios.CancelToken.source();
+          console.log(this.cancelToken);
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token,
+          });
+          console.log(resultChartsData);
+          this.chartData = resultChartsData.data;
+          this.renderChart();
+          this.isError = false;
+          this.loading = false;
+        } catch (error) {
+          this.isError = true;
+          this.loading = false;
+        }
+      }
+    },
+    renderChart() {
+      // 构造3D散点图数据
+      // const trace = {
+      //   x: this.chartData.data[0].xData, // 发电机转速
+      //   y: this.chartData.data[0].yData, // 时间
+      //   z: this.chartData.data[0].zData, // 有功功率
+      //   mode: this.chartData.data[0].mode,
+      //   type: "scatter3d", // 3D 散点图
+      //   marker: {
+      //     size: 2, // 点的大小
+      //     color: this.chartData.data[0].zData, // 根据 Z 数据设置颜色
+      //     //   colorscale: "Viridis", // 色带
+      //     colorscale: this.color1
+      //       ? [
+      //           [0, "#F9FDD2"], // 颜色从 this.color1 开始
+      //           [1, this.color1], // 结束颜色为其他颜色
+      //         ]
+      //       : [
+      //           [0, "#F9FDD2"],
+      //           [0.15, "#E9F6BD"],
+      //           [0.3, "#C2E3B9"],
+      //           [0.45, "#8AC8BE"],
+      //           [0.6, "#5CA8BF"],
+      //           [0.75, "#407DB3"],
+      //           [0.9, "#2E4C9A"],
+      //           [1, "#1B2973"],
+      //         ],
+      //   },
+      // };
+      const trace = {
+        x: this.chartData.data[0].xData, // 发电机转速
+        y: this.chartData.data[0].yData, // 时间
+        z: this.chartData.data[0].zData, // 有功功率
+        mode: "markers", // 强制设置为markers,避免出现线条
+        type: "scatter3d", // 3D 散点图
+        marker: {
+          size: 2, // 点的大小
+          color: this.chartData.data[0].zData, // 根据 Z 数据设置颜色
+          colorscale: this.color1
+            ? [
+                [0, "#F9FDD2"], // 颜色从 this.color1 开始
+                [1, this.color1], // 结束颜色为其他颜色
+              ]
+            : [
+                [0, "#F9FDD2"],
+                [0.15, "#E9F6BD"],
+                [0.3, "#C2E3B9"],
+                [0.45, "#8AC8BE"],
+                [0.6, "#5CA8BF"],
+                [0.75, "#407DB3"],
+                [0.9, "#2E4C9A"],
+                [1, "#1B2973"],
+              ],
+        },
+      };
+
+      const layout = {
+        title: this.chartData.data[0].title,
+        scene: {
+          xaxis: {
+            title: this.chartData.xaixs, // X 轴标题
+          },
+          yaxis: {
+            title: this.chartData.yaixs, // Y 轴标题
+          },
+          zaxis: {
+            title: this.chartData.zaixs, // Z 轴标题
+          },
+          aspectratio: {
+            x: 1.5, // X 轴比例
+            y: 2, // Y 轴比例
+            z: 2, // Z 轴比例(可根据需要调整)
+          },
+
+          camera: {
+            eye: {
+              x: 2, // 眼睛的位置
+              y: 2, // 眼睛的位置
+              z: 2, // 眼睛的位置
+            },
+            up: {
+              x: 1, // 设置上方向
+              y: 0.5, // 设置上方向
+              z: 0.5, // 设置上方向
+            },
+          },
+        },
+        margin: { t: 50, b: 50, l: 50, r: 50 }, // 图表边距
+      };
+
+      Plotly.newPlot(`plotly-3d-chart-` + this.index, [trace], layout);
+    },
+  },
+};
+</script>
+
+<style scoped>
+/* 样式可以根据需求自定义 */
+#plotly-3d-chart {
+  width: 100%;
+  height: 500px;
+}
+</style>

+ 28 - 7
src/views/performance/components/chartsCom/BarChart.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-09-11 14:30:17
- * @LastEditTime: 2025-01-17 16:56:02
+ * @LastEditTime: 2025-01-20 09:16:32
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/BarChart.vue
@@ -28,7 +28,13 @@
     </div>
 
     <!-- 图表容器 -->
-    <div :id="`bar-chart${inds}`" style="width: 100%; height: 500px"></div>
+    <div
+      v-loading="loading"
+      :id="`bar-chart${inds}`"
+      style="width: 100%; height: 400px"
+    >
+      <el-empty v-if="isError" description="请求失败"></el-empty>
+    </div>
   </div>
 </template>
 
@@ -36,6 +42,7 @@
 import { nextTick } from "vue"; // 导入 nextTick
 import Plotly from "plotly.js-dist";
 import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin";
 
 export default {
   props: {
@@ -50,6 +57,7 @@ export default {
       },
     },
   },
+  mixins: [myMixin],
   data() {
     return {
       chartData: {
@@ -58,7 +66,13 @@ export default {
         engineTypeName: "",
         xaixs: "",
         yaixs: "",
-        data: [],
+        data: [
+          // {
+          //   xData: ["2024-01-01", "2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05"],
+          //   yData: [10, 20, 30, 40, 50],
+          //   title: "数据集1",
+          // },
+        ],
       },
       chartType: "bar", // 当前图表类型 ('bar' 或 'scatter')
       color1: "#406DAB", // 默认颜色
@@ -73,22 +87,28 @@ export default {
     async getData() {
       if (this.fileAddr !== "") {
         try {
-          const resultChartsData = await axios.get(this.fileAddr);
+          this.loading = true;
+          this.cancelToken = axios.CancelToken.source();
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token,
+          });
           this.chartData = resultChartsData.data;
           // 使用 nextTick 来确保 DOM 渲染完成后绘制图表
           nextTick(() => {
             this.drawChart();
+            this.isError = false;
+            this.loading = false;
           });
-          // this.$emit("getResult", { index: this.index, result: "success" });
         } catch (error) {
           console.error("Error loading data:", error);
-          // this.$emit("getResult", { index: this.index, result: "error" });
+          this.isError = true;
+          this.loading = false;
         }
       }
     },
     // 绘制图表
     drawChart() {
-      if (!this.chartData.data.length) return;
+      if (this.chartData.data.length === 0) return;
 
       const chartDataset = this.chartData.data[0];
       const trace = {
@@ -143,6 +163,7 @@ export default {
           t: 50,
           b: 50,
         },
+        autosize: true, // 开启自适应
       };
 
       // 渲染图表

+ 17 - 4
src/views/performance/components/chartsCom/BoxLineCharts.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-09-11 14:32:51
- * @LastEditTime: 2025-01-17 18:54:17
+ * @LastEditTime: 2025-01-16 18:29:08
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/BoxLineCharts.vue
@@ -158,14 +158,18 @@ export default {
 <template>
   <div>
     <!-- boxLineCharts -->
-    <div :id="`plotDivBox-${index}`" style="width: 100%; height: 550px"></div>
+    <div v-loading="loading" :id="`plotDivBox-${index}`" style="width: 100%; height: 550px">
+      <el-empty v-if="isError" description="请求失败"></el-empty>
+    </div>
   </div>
 </template>
 
 <script>
 import Plotly from "plotly.js-dist";
 import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin";
 export default {
+  mixins: [myMixin],
   props: {
     fileAddr: {
       default: "",
@@ -187,10 +191,19 @@ export default {
     async getData() {
       if (this.fileAddr !== "") {
         try {
-          const resultChartsData = await axios.get(this.fileAddr);
+          this.loading = true
+          this.cancelToken = axios.CancelToken.source();
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token
+          });
           this.chartData = resultChartsData.data;
           this.drawBoxPlot();
-        } catch (error) {}
+          this.loading = false
+          this.isError = false
+        } catch (error) {
+          this.loading = false
+          this.isError = true
+        }
       }
     },
     drawBoxPlot() {

+ 17 - 3
src/views/performance/components/chartsCom/BoxMarkersCharts.vue

@@ -17,15 +17,19 @@
  -->
 <template>
   <div>
-    <div ref="plotlyChart" style="width: 100%; height: 600px"></div>
+    <div v-loading="loading" ref="plotlyChart" style="width: 100%; height: 600px">
+      <el-empty v-if="isError" description="请求失败"></el-empty>
+    </div>
   </div>
 </template>
 
 <script>
 import Plotly from "plotly.js-dist-min";
 import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin";
 export default {
   name: "BoxPlotWithMedians",
+  mixins: [myMixin],
   props: {
     fileAddr: {
       default: "",
@@ -47,10 +51,20 @@ export default {
     async getData() {
       if (this.fileAddr !== "") {
         try {
-          const resultChartsData = await axios.get(this.fileAddr);
+          this.loading=true
+          this.cancelToken = axios.CancelToken.source();
+          console.log(this.cancelToken)
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token
+          });
           this.chartData = resultChartsData.data;
           this.drawBoxPlot();
-        } catch (error) {}
+          this.isError = false
+          this.loading = false
+        } catch (error) {
+          this.isError = true
+          this.loading = false
+        }
       }
     },
     drawBoxPlot() {

+ 19 - 44
src/views/performance/components/chartsCom/NoColourBandTwoDMarkerChart.vue

@@ -7,10 +7,9 @@
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/NoColourBandTwoDMarkerChart.vue
 -->
 <template>
-  <div style="min-height: 300px">
-    <div v-inview="handleDomInView"></div>
+  <div style="height: 400px">
     <!-- 2D散点图 没色带 -->
-    <template v-if="isShow === true">
+    <template>
       <div style="display: flex; align-items: center; margin-top: 20px">
         <div style="margin-right: 20px; display: flex; align-items: center">
           <el-color-picker
@@ -31,12 +30,8 @@
           >
         </div>
       </div>
-      <div v-loading="$parent.requestRecord[index] === 'start'">
-        <el-empty
-          v-if="result[index] === 'error'"
-          description="请求失败"
-        ></el-empty>
-        <div v-else ref="plotlyChart" style="height: 400px"></div>
+      <div v-loading="loading" ref="plotlyChart" style="height: 400px">
+        <el-empty v-if="isError" description="请求失败"></el-empty>
       </div>
     </template>
   </div>
@@ -45,7 +40,10 @@
 <script>
 import Plotly from "plotly.js-dist";
 import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin";
+
 export default {
+  mixins: [myMixin],
   props: {
     fileAddr: {
       default: "",
@@ -53,11 +51,7 @@ export default {
     },
     index: {
       type: Number,
-    },
-    result: {
-      type: Array,
-      default: [],
-    },
+    }
   },
   data() {
     return {
@@ -67,47 +61,28 @@ export default {
       selectedPoints: [],
       originalColors: [],
       originalSizes: [],
-      isShow: undefined,
     };
   },
-  watch: {
-    result: {
-      deep: true,
-      handler(v) {
-        console.log("-----------------------", v);
-        const startIndex = this.$parent.requestRecord.findIndex(
-          (item) => item === "start"
-        );
-        if (startIndex > -1) {
-          if (startIndex === this.index) {
-            this.getData();
-          }
-        }
-      },
-    },
-  },
   async mounted() {
-    if (this.index === 0) {
-      this.getData();
-    }
+    this.getData();
   },
   methods: {
-    handleDomInView(isInView) {
-      if (isInView && this.isShow === undefined) {
-        this.isShow = isInView;
-        this.$emit("changeRequestNum", this.index);
-      }
-      console.log(this.isShow);
-    },
     async getData() {
       if (this.fileAddr !== "") {
         try {
-          const resultChartsData = await axios.get(this.fileAddr);
+          this.loading = true
+          this.cancelToken = axios.CancelToken.source();
+          console.log(this.cancelToken)
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token
+          });
           this.chartData = resultChartsData.data;
           this.drawChart();
-          this.$emit("getResult", { index: this.index, result: "success" });
+          this.isError = false
+          this.loading = false
         } catch (error) {
-          this.$emit("getResult", { index: this.index, result: "error" });
+          this.isError = true
+          this.loading = false
         }
       }
     },

+ 51 - 48
src/views/performance/components/chartsCom/TwoDMarkersChart.vue

@@ -1,9 +1,8 @@
 <template>
-  <div style="min-height: 300px">
-    <div v-inview="handleDomInView"></div>
+  <div style="height: 452px">
     <!-- 2D散点图 -->
-    <template v-if="isShow === true">
-      <div style="display: flex; align-items: center; margin-top: 20px">
+    <template>
+      <div style="display: flex; align-items: center; padding-top: 20px">
         <div style="margin-right: 20px; display: flex; align-items: center">
           <el-color-picker
             size="small"
@@ -21,15 +20,16 @@
           <el-button size="small" @click="setChartType('line')"
             >折线图</el-button
           >
+          <el-button size="small" @click="setChartType('bar')"
+            >柱状图</el-button
+          >
         </div>
       </div>
-      <div v-loading="$parent.requestRecord[index] === 'start'">
-        <el-empty
-          v-if="result[index] === 'error'"
-          description="请求失败"
-        ></el-empty>
-        <div v-else ref="plotlyChart" style="height: 400px"></div>
+      <!-- <div v-loading="$parent.requestRecord[index] === 'start'"> -->
+      <div v-loading="loading" ref="plotlyChart" style="height: 400px">
+        <el-empty v-if="isError" description="请求失败"></el-empty>
       </div>
+      <!-- </div> -->
     </template>
   </div>
 </template>
@@ -37,73 +37,76 @@
 <script>
 import Plotly from "plotly.js-dist";
 import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin";
+
 export default {
   props: {
     fileAddr: {
       default: "",
       type: String,
     },
-    index: {
-      type: Number,
-    },
-    result: {
-      type: Array,
-      default: [],
-    },
   },
   data() {
     return {
-      chartData: {},
+      chartData: {
+        // analysisTypeCode: "动态偏航误差",
+        // engineCode: "WEM00026",
+        // engineTypeName: "",
+        // xaixs: "对风角度(度)",
+        // yaixs: "风速(m/s)",
+        // data: [
+        //   {
+        //     engineName: "#01",
+        //     engineCode: "WOG00935",
+        //     title: "动态偏航误差分析-#01",
+        //     xData: [
+        //       -15.4, -9.2, 4, 7, 9, -6.7, -5.2, -3.9, 0.9, 5.4, 6.4, 12.5, -8.1,
+        //       3.0, -4.5,
+        //     ],
+        //     yData: [
+        //       3.3, 3.7, 1290.0, 10, 7, 8, 858.0, 987.0, 1159.0, 1091.0, 979.0,
+        //       1023.5, 1210.1, 1105.4, 970.2,
+        //     ],
+        //     colorbartitle: "密度",
+        //   },
+        // ],
+      },
       chartType: "scatter", // 初始化为散点图 (scatter)
       color1: "", // 默认颜色
       selectedPoints: [],
       originalColors: [],
       originalSizes: [],
-      isShow: undefined,
     };
   },
-  watch: {
-    result: {
-      deep: true,
-      handler(v) {
-        console.log("-----------------------", v);
-        const startIndex = this.$parent.requestRecord.findIndex(
-          (item) => item === "start"
-        );
-        if (startIndex > -1) {
-          if (startIndex === this.index) {
-            this.getData();
-          }
-        }
-      },
-    },
-  },
+  mixins: [myMixin],
   async mounted() {
-    if (this.index === 0) {
-      this.getData();
-    }
+    this.getData();
   },
   methods: {
-    handleDomInView(isInView) {
-      if (isInView && this.isShow === undefined) {
-        this.isShow = isInView;
-        this.$emit("changeRequestNum", this.index);
-      }
-      console.log(this.isShow);
-    },
     async getData() {
       if (this.fileAddr !== "") {
         try {
-          const resultChartsData = await axios.get(this.fileAddr);
+          this.loading = true;
+          this.cancelToken = axios.CancelToken.source();
+          console.log(this.cancelToken);
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token,
+          });
+          console.log(resultChartsData);
           this.chartData = resultChartsData.data;
           this.drawChart();
-          this.$emit("getResult", { index: this.index, result: "success" });
+          this.isError = false;
+          this.loading = false;
         } catch (error) {
-          this.$emit("getResult", { index: this.index, result: "error" });
+          this.isError = true;
+          this.loading = false;
         }
       }
     },
     drawChart() {
+      if (!this.$refs.plotlyChart) {
+        return false;
+      }
       const data = this.chartData.data && this.chartData.data[0];
       let trace = {};
       // 保存原始颜色和大小

+ 17 - 5
src/views/performance/components/chartsCom/WindRoseChart.vue

@@ -1,12 +1,16 @@
 <template>
   <div>
-    <div :id="`plotDiv-${inds}`" style="width: 100%; height: 550px"></div>
+    <div v-loading="loading" :id="`plotDiv-${inds}`" style="width: 100%; height: 550px">
+      <el-empty v-if="isError" description="请求失败"></el-empty>
+    </div>
   </div>
 </template>
 
 <script>
 import Plotly from "plotly.js-dist";
 import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin";
+
 export default {
   props: {
     fileAddr: {
@@ -19,6 +23,7 @@ export default {
       default: 1,
     },
   },
+  mixins: [myMixin],
   data() {
     return {
       // 数据结构
@@ -42,13 +47,20 @@ export default {
     async getData() {
       if (this.fileAddr !== "") {
         try {
-          const resultChartsData = await axios.get(this.fileAddr);
+          this.loading = true
+          this.cancelToken = axios.CancelToken.source();
+          console.log(this.cancelToken)
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token
+          });
+          console.log(resultChartsData)
           this.chartData = resultChartsData.data;
-          console.log(this.chartData, "this.chartData");
           this.renderChart();
-          this.$emit("getResult", { index: this.index, result: "success" });
+          this.isError = false
+          this.loading = false
         } catch (error) {
-          this.$emit("getResult", { index: this.index, result: "error" });
+          this.isError = true
+          this.loading = false
         }
       }
     },

+ 143 - 10
src/views/performance/components/chartsCom/lineAndChildLine.vue

@@ -6,7 +6,7 @@
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/lineAndChildLine.vue
 -->
-<template>
+<!-- <template>
   <div>
     lineAndChildLine
     <h1>有功功率曲线分析</h1>
@@ -17,25 +17,158 @@
     <h1>叶尖速比和风速分析</h1>
     <div :id="`chart-${inds}`" style="width: 100%; height: 550px"></div>
   </div>
+</template> -->
+<template>
+  <div>
+    <!-- 图表控制面板 -->
+    <div style="display: flex; align-items: center">
+      <div style="margin-right: 20px; display: flex; align-items: center">
+        <el-color-picker size="small" v-model="color1" show-alpha @change="updateChartColor"></el-color-picker>
+        <span style="margin-left: 10px">自定义颜色</span>
+      </div>
+      <div>
+        <el-button size="small" @click="toggleChartType">
+          切换为{{ chartType === "line" ? "柱状图" : "折线图" }}
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 图表容器 -->
+    <div v-loading="loading" :id="`bar-chart${inds}`" style="width: 100%; height: 400px">
+      <el-empty v-if="isError" description="请求失败"></el-empty>
+    </div>
+  </div>
 </template>
+
 <script>
-import { allTypesDatas } from "@/utils/allTypesOfAnalysisData.js";
+import { nextTick } from "vue"; // 导入 nextTick
 import Plotly from "plotly.js-dist";
+import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin"; // 假设你需要的 mixin
+
 export default {
-  props: {},
+  props: {
+    fileAddr: {
+      type: String,
+      default: "",
+    },
+    inds: {
+      type: Number,
+      default() {
+        return 0;
+      },
+    },
+  },
+  mixins: [myMixin],
   data() {
-    return {};
+    return {
+      chartData: {
+        analysisTypeCode: "示例数据分析",
+        engineCode: "引擎001",
+        engineTypeName: "示例引擎",
+        xaixs: "时间",
+        yaixs: "数值",
+        data: [
+          {
+            xData: ["2024-01-01", "2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05"],
+            yData: [10, 20, 30, 40, 50],
+            title: "数据集1",
+          },
+        ],
+      },
+      chartType: "line", // 默认图表类型是折线图
+      color1: "#406DAB", // 默认颜色
+      loading: false,
+      isError: false,
+    };
   },
   mounted() {
-    this.initcharts();
+    if (this.fileAddr) {
+      this.getData();
+    } else {
+      this.drawChart(); // 如果没有文件地址,直接绘制模拟数据
+    }
   },
   methods: {
-    initcharts() {
-      const lineDatas = allTypesDatas.filter(
-        (item) => item.analysisTypeCode === "temperature_large_components"
-      )[0];
+    // 获取数据
+    async getData() {
+      if (this.fileAddr !== "") {
+        try {
+          this.loading = true;
+          this.cancelToken = axios.CancelToken.source();
+          // const resultChartsData = await axios.get(this.fileAddr, {
+          //   cancelToken: this.cancelToken.token,
+          // });
+          // this.chartData = resultChartsData.data;
+          // 使用 nextTick 来确保 DOM 渲染完成后绘制图表
+          nextTick(() => {
+            this.drawChart();
+            this.isError = false;
+            this.loading = false;
+          });
+        } catch (error) {
+          console.error("Error loading data:", error);
+          this.isError = true;
+          this.loading = false;
+        }
+      }
+    },
+    // 绘制图表
+    drawChart() {
+      const chartDataset = this.chartData.data[0];
+      const trace = {
+        x: chartDataset.xData, // 横坐标数据
+        y: chartDataset.yData, // 纵坐标数据
+        type: this.chartType, // 当前图表类型 ('line' 或 'bar')
+        marker: {
+          color: this.color1, // 图表颜色
+        },
+        line: {
+          color: this.color1, // 折线图颜色
+        },
+        name: chartDataset.title || "数据", // 图例名称
+      };
+
+      const layout = {
+        title: this.chartData.analysisTypeCode || "图表", // 图表标题
+        xaxis: {
+          title: this.chartData.xaixs || "X轴", // 横坐标标题
+        },
+        yaxis: {
+          title: this.chartData.yaixs || "Y轴", // 纵坐标标题
+        },
+        margin: {
+          l: 50,
+          r: 50,
+          t: 50,
+          b: 50,
+        },
+        autosize: true, // 开启自适应
+      };
+
+      // 渲染图表
+      Plotly.newPlot(
+        `bar-chart${this.inds}`,
+        [trace,trace],
+        layout,
+        {
+          responsive: true,
+        }
+      );
+    },
+    // 切换图表类型
+    toggleChartType() {
+      this.chartType = this.chartType === "line" ? "bar" : "line";
+      this.drawChart();
+    },
+    // 更新图表颜色
+    updateChartColor() {
+      this.drawChart();
     },
   },
 };
 </script>
-<style scoped></style>
+
+<style scoped>
+/* 样式可以根据需求自定义 */
+</style>

+ 35 - 63
src/views/performance/components/chartsCom/powerMarkers2DCharts.vue

@@ -143,26 +143,16 @@ export default {
 <!-- <style scoped></style> -->
 <template>
   <div style="min-height: 300px">
-    <div v-inview="handleDomInView"></div>
     <!-- 2D散点图 -->
-    <template v-if="isShow === true">
+    <template>
       <div style="display: flex; align-items: center; margin-top: 20px">
         <div style="margin-right: 20px; display: flex; align-items: center">
-          <el-color-picker
-            size="small"
-            v-model="color1"
-            show-alpha
-            @change="updateChartColor"
-          ></el-color-picker>
+          <el-color-picker size="small" v-model="color1" show-alpha @change="updateChartColor"></el-color-picker>
           <span style="margin-left: 10px">自定义颜色</span>
         </div>
       </div>
-      <div v-loading="$parent.requestRecord[index] === 'start'">
-        <el-empty
-          v-if="result[index] === 'error'"
-          description="请求失败"
-        ></el-empty>
-        <div v-else ref="plotlyChart" style="height: 400px"></div>
+      <div v-loading="loading" ref="plotlyChart" style="height: 400px">
+        <el-empty v-if="isError" description="请求失败"></el-empty>
       </div>
     </template>
   </div>
@@ -171,8 +161,10 @@ export default {
 <script>
 import Plotly from "plotly.js-dist";
 import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin";
 
 export default {
+  mixins: [myMixin],
   props: {
     fileAddr: {
       default: "",
@@ -181,10 +173,6 @@ export default {
     index: {
       type: Number,
     },
-    result: {
-      type: Array,
-      default: [],
-    },
   },
   data() {
     return {
@@ -194,46 +182,30 @@ export default {
       selectedPoints: [],
       originalColors: [],
       originalSizes: [],
-      isShow: undefined,
     };
   },
-  watch: {
-    result: {
-      deep: true,
-      handler(v) {
-        const startIndex = this.$parent.requestRecord.findIndex(
-          (item) => item === "start"
-        );
-        if (startIndex > -1 && startIndex === this.index) {
-          this.getData();
-        }
-      },
-    },
-  },
   async mounted() {
-    if (this.index === 0) {
-      this.getData();
-    }
+    this.getData();
   },
   methods: {
-    handleDomInView(isInView) {
-      if (isInView && this.isShow === undefined) {
-        this.isShow = isInView;
-        this.$emit("changeRequestNum", this.index);
-      }
-      console.log(this.isShow);
-    },
     async getData() {
       if (this.fileAddr !== "") {
-        // try {
-        const resultChartsData = await axios.get(this.fileAddr);
-        this.chartData = resultChartsData.data;
-        console.log(this.chartData, "this.chartData");
-        this.drawChart();
-        this.$emit("getResult", { index: this.index, result: "success" });
-        // } catch (error) {
-        //   this.$emit("getResult", { index: this.index, result: "error" });
-        // }
+        try {
+          this.loading = true
+          this.cancelToken = axios.CancelToken.source();
+          console.log(this.cancelToken)
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token
+          });
+          console.log(resultChartsData)
+          this.chartData = resultChartsData.data;
+          this.drawChart();
+          this.isError = false
+          this.loading = false
+        } catch (error) {
+          this.isError = true
+          this.loading = false
+        }
       }
     },
     drawChart() {
@@ -267,19 +239,19 @@ export default {
             color: data.yData, // 根据 yData 设置颜色
             colorscale: this.color1
               ? [
-                  [0, "#F9FDD2"], // 颜色从 this.color1 开始
-                  [1, this.color1], // 结束颜色为其他颜色
-                ]
+                [0, "#F9FDD2"], // 颜色从 this.color1 开始
+                [1, this.color1], // 结束颜色为其他颜色
+              ]
               : [
-                  [0, "#F9FDD2"],
-                  [0.15, "#E9F6BD"],
-                  [0.3, "#C2E3B9"],
-                  [0.45, "#8AC8BE"],
-                  [0.6, "#5CA8BF"],
-                  [0.75, "#407DB3"],
-                  [0.9, "#2E4C9A"],
-                  [1, "#1B2973"],
-                ],
+                [0, "#F9FDD2"],
+                [0.15, "#E9F6BD"],
+                [0.3, "#C2E3B9"],
+                [0.45, "#8AC8BE"],
+                [0.6, "#5CA8BF"],
+                [0.75, "#407DB3"],
+                [0.9, "#2E4C9A"],
+                [1, "#1B2973"],
+              ],
             colorbar: {
               title: data.colorbartitle, // 色标标题
             },

+ 2 - 2
vue.config.js

@@ -66,8 +66,8 @@ module.exports = {
         // target: "http://192.168.5.4:16200", // 石月
         // target: "http://192.168.50.235:16200", // 内网
         // target: "http://192.168.5.15:16200",
-        // target: "http://192.168.50.235:16500", //演示环境
-        target: "http://106.120.102.238:26500", //外网演示环境
+        target: "http://192.168.50.235:16500", //演示环境
+        // target: "http://106.120.102.238:26500", //外网演示环境
         // target: "http://106.120.102.238:16700", // 外网16700  生产16600
         // target: "http://10.96.137.5",
         changeOrigin: true,