rui.jiang 10 mesi fa
parent
commit
8411f185d6
44 ha cambiato i file con 3755 aggiunte e 543 eliminazioni
  1. BIN
      1.14.zip
  2. BIN
      1.15.zip
  3. BIN
      src.zip
  4. 80 0
      src/components/virtual_list/ManyVirtualList.vue
  5. 24 24
      src/components/virtual_list/index.vue
  6. 6 5
      src/main.js
  7. 1 1
      src/utils/request.js
  8. 300 3
      src/views/overview/components/cp/index.vue
  9. 17 18
      src/views/overview/components/cp_trend/index.vue
  10. 300 3
      src/views/overview/components/cp_windspeed/index.vue
  11. 51 27
      src/views/overview/components/data_integrity_minute/index.vue
  12. 279 3
      src/views/overview/components/data_integrity_second/index.vue
  13. 8 7
      src/views/overview/components/filterChart/index.vue
  14. 286 3
      src/views/overview/components/pitch_generator_speed/index.vue
  15. 286 3
      src/views/overview/components/pitch_power/index.vue
  16. 19 20
      src/views/overview/components/pitch_tsr_cp/index.vue
  17. 19 19
      src/views/overview/components/power_curve/index.vue
  18. 20 20
      src/views/overview/components/power_scatter/index.vue
  19. 19 20
      src/views/overview/components/power_scatter_2D/index.vue
  20. 22 21
      src/views/overview/components/rated_power_windspeed/index.vue
  21. 20 20
      src/views/overview/components/rated_windspeed/index.vue
  22. 357 3
      src/views/overview/components/speed_power/index.vue
  23. 374 2
      src/views/overview/components/speed_torque/index.vue
  24. 20 20
      src/views/overview/components/temperature_environment/index.vue
  25. 10 2
      src/views/overview/components/temperature_large_components/index.vue
  26. 297 3
      src/views/overview/components/tsr/index.vue
  27. 43 38
      src/views/overview/components/tsr_cp_power/index.vue
  28. 21 20
      src/views/overview/components/tsr_cp_power_scatter/index.vue
  29. 18 22
      src/views/overview/components/tsr_trend/index.vue
  30. 297 3
      src/views/overview/components/tsr_windspeed/index.vue
  31. 20 21
      src/views/overview/components/wind_speed/index.vue
  32. 20 22
      src/views/overview/components/wind_speed_frequency/index.vue
  33. 19 19
      src/views/overview/components/yaw_error_density/index.vue
  34. 2 2
      src/views/performance/components/EditAnalysis.vue
  35. 2 2
      src/views/performance/components/analysisEvent.vue
  36. 17 8
      src/views/performance/components/chartsCom/3DDrawingChart.vue
  37. 2 2
      src/views/performance/components/chartsCom/BarChart.vue
  38. 12 8
      src/views/performance/components/chartsCom/BoxLineCharts.vue
  39. 177 50
      src/views/performance/components/chartsCom/HeatmapCharts.vue
  40. 0 3
      src/views/performance/components/chartsCom/TwoDMarkersChart.vue
  41. 82 73
      src/views/performance/components/chartsCom/lineAndChildLine.vue
  42. 205 0
      src/views/performance/components/chartsCom/lineChartsFen.vue
  43. 3 3
      src/views/performance/editAssets.vue
  44. BIN
      归档.zip

BIN
1.14.zip


BIN
1.15.zip


BIN
src.zip


+ 80 - 0
src/components/virtual_list/ManyVirtualList.vue

@@ -0,0 +1,80 @@
+<!--
+ * @Author: your name
+ * @Date: 2025-01-20 16:36:35
+ * @LastEditTime: 2025-01-20 16:36:35
+ * @LastEditors: your name
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/components/virtual_list/ManyVirtualList.vue
+-->
+<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="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>

+ 24 - 24
src/components/virtual_list/index.vue

@@ -1,18 +1,20 @@
 <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 }">
+  <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="list"
+        :item-size="itemSize"
+        :key-field="keyField"
+        v-slot="{ item, index }"
+      >
         <slot :item="item" :index="index"></slot>
       </RecycleScroller>
     </div>
@@ -28,23 +30,21 @@ export default {
   props: {
     list: {
       type: Array,
-      default: () => []
+      default: () => [],
     },
     keyField: {
       type: String,
-      default: 'id'
+      default: "id",
     },
     itemSize: {
       type: Number,
-      default: 300
-    }
+      default: 300,
+    },
   },
   data() {
-    return {
-
-    }
-  }
-}
+    return {};
+  },
+};
 </script>
 
 <style lang="scss" scoped>
@@ -69,4 +69,4 @@ export default {
     height: 0;
   }
 }
-</style>
+</style>

+ 6 - 5
src/main.js

@@ -16,9 +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 "vue-virtual-scroller/dist/vue-virtual-scroller.css";
 import VirtualList from "@/components/virtual_list/index.vue";
-
+import ManyVirtualList from "@/components/virtual_list/ManyVirtualList.vue";
 
 Vue.component("VueDraggableResizable", VueDraggableResizable);
 Vue.component("SvgIcons", SvgIcons);
@@ -38,12 +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('VirtualList', VirtualList)
+Vue.component("RecycleScroller", RecycleScroller);
+Vue.component("VirtualList", VirtualList);
+Vue.component("ManyVirtualList", ManyVirtualList);
 
 Vue.use(ElementUI);
 // 引入tailwind

+ 1 - 1
src/utils/request.js

@@ -4,7 +4,7 @@ import { Message } from "element-ui";
 const service = axios.create({
   baseURL: window?._BASE_CONFIG?.API || "/api",
   withCredentials: true,
-  timeout: 5000,
+  timeout: 10000,
 });
 
 const writeList = ["/api/energy-manage-service/sysuserinfo/open/userLogin"];

+ 300 - 3
src/views/overview/components/cp/index.vue

@@ -1,17 +1,314 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:05:58
- * @LastEditTime: 2025-01-10 09:28:15
+ * @LastEditTime: 2025-01-20 13:31:38
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/cp/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">
+          分析风力发电机组的Cp值对于优化其性能和增强效率至关重要:通过测量和分析Cp,可以直观了解风机的效率。Cp值越接近贝兹极限,说明风机的设计和运行越高效。
+        </div>
+        <div style="font-size: 12px; margin-top: 10px">
+          Cp的分析也是监测风机性能的重要手段。如果Cp值出现异常下降,可能预示着机械故障、叶片磨损或其他维护需求。
+        </div>
+      </el-alert>
+
+      <div
+        class="titleCharts"
+        v-if="generalFilesDatas && generalFilesDatas.length > 0"
+      >
+        分析总图 :
+      </div>
+      <div v-for="(item, index) in generalFilesDatas">
+        <lineAndChildLine
+          :key="item.batchCode + index"
+          :index="index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineAndChildLine>
+      </div>
+      <div
+        class="titleCharts"
+        v-if="diagramRelationsDatas && diagramRelationsDatas.length > 0"
+      >
+        分析分图 :
+      </div>
+      <div v-for="(item, index) in diagramRelationsDatas">
+        <lineChartsFen
+          :key="item.fieldEngineCode + index"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fieldEngineCode="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineChartsFen>
+      </div>
+
+      <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 lineChartsFen from "@/views/performance/components/chartsCom/lineChartsFen.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "cp",
+  components: {
+    DicCard,
+    FilterChart,
+    lineAndChildLine,
+    lineChartsFen,
+    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>

+ 17 - 18
src/views/overview/components/cp_trend/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:06:09
- * @LastEditTime: 2025-01-20 09:21:51
+ * @LastEditTime: 2025-01-20 13:32:08
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/cp_trend/index.vue
@@ -283,26 +283,25 @@ export default {
     padding: 20px;
     flex: 1;
     &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
-
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 300 - 3
src/views/overview/components/cp_windspeed/index.vue

@@ -1,17 +1,314 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:08:00
- * @LastEditTime: 2025-01-10 09:20:32
+ * @LastEditTime: 2025-01-20 13:32:39
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/cp_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">
+          分析风力发电机组的Cp值对于优化其性能和增强效率至关重要:通过测量和分析Cp,可以直观了解风机的效率。Cp值越接近贝兹极限,说明风机的设计和运行越高效。
+        </div>
+        <div style="font-size: 12px; margin-top: 10px">
+          Cp的分析也是监测风机性能的重要手段。如果Cp值出现异常下降,可能预示着机械故障、叶片磨损或其他维护需求。
+        </div>
+      </el-alert>
+
+      <div
+        class="titleCharts"
+        v-if="generalFilesDatas && generalFilesDatas.length > 0"
+      >
+        分析总图 :
+      </div>
+      <div v-for="(item, index) in generalFilesDatas">
+        <lineAndChildLine
+          :key="item.batchCode + index"
+          :index="index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineAndChildLine>
+      </div>
+      <div
+        class="titleCharts"
+        v-if="diagramRelationsDatas && diagramRelationsDatas.length > 0"
+      >
+        分析分图 :
+      </div>
+      <div v-for="(item, index) in diagramRelationsDatas">
+        <lineChartsFen
+          :key="item.fieldEngineCode + index"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fieldEngineCode="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineChartsFen>
+      </div>
+
+      <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 lineChartsFen from "@/views/performance/components/chartsCom/lineChartsFen.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "cpWindspeed",
+  components: {
+    DicCard,
+    FilterChart,
+    lineAndChildLine,
+    lineChartsFen,
+    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>

+ 51 - 27
src/views/overview/components/data_integrity_minute/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 17:54:02
- * @LastEditTime: 2025-01-17 09:23:35
+ * @LastEditTime: 2025-01-20 15:55:21
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/data_integrity_minute/index.vue
@@ -36,8 +36,18 @@
           数据完整度分析是根据数据统计周期内数据总行数与期望数据总行数的比值计算出来的。
         </div>
       </el-alert>
+      <template v-if="generalFilesDatas && generalFilesDatas.length > 0">
+        <div v-for="(item, index) in generalFilesDatas">
+          <HeatmapCharts
+            :key="item.batchCode + index"
+            :index="item.batchCode + index"
+            :ref="item.batchCode"
+            :fileAddr="item.fileAddr"
+          ></HeatmapCharts>
+        </div>
+      </template>
+      <el-empty description="暂无分析记录" v-else></el-empty>
 
-      <HeatmapCharts></HeatmapCharts>
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -58,7 +68,12 @@
       </el-row>
     </div>
     <div class="right">
-      <DicCard></DicCard>
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
     </div>
   </div>
 </template>
@@ -68,7 +83,6 @@ import FilterChart from "@/views/overview/components/filterChart/index.vue";
 import HeatmapCharts from "@/views/performance/components/chartsCom/HeatmapCharts.vue";
 import TinymceEditor from "@/components/Tinymce.vue";
 import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
-
 export default {
   name: "DataIntegrityMinute",
   components: {
@@ -96,10 +110,15 @@ export default {
       form: {
         value2: "",
       },
+
+      commentDescriptionVos: [], //评论列表
       windEngineGroupList: [], //批次风机列表
       fieldEngineCodes: [], //选中风机
       comment: "",
       options: [],
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图,
+      editableTabs: [],
     };
   },
   watch: {
@@ -174,7 +193,34 @@ export default {
               ? undefined
               : this.fieldEngineCodes.join(","),
         });
-        console.log(result, "result");
+        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);
       }
@@ -236,28 +282,6 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
-
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
-
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
-
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
-
   }
   .right {
     width: 250px;

+ 279 - 3
src/views/overview/components/data_integrity_second/index.vue

@@ -1,17 +1,293 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 17:55:01
- * @LastEditTime: 2025-01-10 09:20:15
+ * @LastEditTime: 2025-01-20 15:50:16
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/data_integrity_second/index.vue
 -->
+
 <template>
-  <div>秒级钟级SCADA数据完整度分析</div>
+  <div class="type-variable">
+    <!-- 秒级钟级SCADA数据完整度分析 -->
+    <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">
+          风电机组SCADA数据完整度分析是对风电场运行数据质量进行评估的关键环节。
+        </div>
+        <div style="font-size: 12px; margin-top: 10px">
+          数据完整度分析可以帮助识别数据缺失、异常或噪声,确保所采集数据的准确性和连贯性。这对于后续的风电机组运行分析和故障诊断至关重要。
+        </div>
+        <div style="font-size: 12px; margin-top: 10px">
+          数据完整度分析是根据数据统计周期内数据总行数与期望数据总行数的比值计算出来的。
+        </div>
+      </el-alert>
+      <template v-if="generalFilesDatas && generalFilesDatas.length > 0">
+        <div v-for="(item, index) in generalFilesDatas">
+          <HeatmapCharts
+            :key="item.batchCode + index"
+            :index="item.batchCode + index"
+            :ref="item.batchCode"
+            :fileAddr="item.fileAddr"
+          ></HeatmapCharts>
+        </div>
+      </template>
+      <el-empty description="暂无分析记录" v-else></el-empty>
+
+      <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 HeatmapCharts from "@/views/performance/components/chartsCom/HeatmapCharts.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
 export default {
   name: "DataIntegritySecond",
+  components: {
+    DicCard,
+    FilterChart,
+    HeatmapCharts,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+
+      commentDescriptionVos: [], //评论列表
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图,
+      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 {
+        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();
+      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+    },
+    //下一条
+    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;
+  }
+}
+</style>

+ 8 - 7
src/views/overview/components/filterChart/index.vue

@@ -1,8 +1,8 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-13 14:53:21
- * @LastEditTime: 2025-01-14 13:44:55
- * @LastEditors: bogon
+ * @LastEditTime: 2025-01-20 17:24:03
+ * @LastEditors: milo-MacBook-Pro.local
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/filterChart/index.vue
 -->
@@ -54,11 +54,12 @@ export default {
   methods: {
     onSearch() {
       console.log(this.form.value2);
-      if (this.form.value2 && this.form.value2.length > 0) {
-        this.$emit("getEnfineList", this.form.value2);
-      } else {
-        this.$message.warning("请选择风机后进行查询");
-      }
+      // if (this.form.value2 && this.form.value2.length > 0) {
+      this.$emit("getEnfineList", this.form.value2);
+      // }
+      // else {
+      //   this.$message.warning("请选择风机后进行查询");
+      // }
     },
     onSubmit(type) {
       if (type === "handlePrevious") {

+ 286 - 3
src/views/overview/components/pitch_generator_speed/index.vue

@@ -1,17 +1,300 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:09:25
- * @LastEditTime: 2025-01-10 09:19:31
+ * @LastEditTime: 2025-01-20 13:35:52
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/pitch_generator_speed/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></div>
+      <div class="titleCharts">分析分图 :</div>
+      <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
+            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 TwoDMarkersChart from "@/views/performance/components/chartsCom/TwoDMarkersChart.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import {
+  analysisDetail,
+  queryAnalysisedEngine,
+  analysisCommentEdit,
+} from "@/api/performance";
+
 export default {
   name: "pitchGeneratorSpeed",
+  components: {
+    DicCard,
+    FilterChart,
+    TwoDMarkersChart,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      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 {
+        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>

+ 286 - 3
src/views/overview/components/pitch_power/index.vue

@@ -1,17 +1,300 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:09:41
- * @LastEditTime: 2025-01-10 09:19:07
+ * @LastEditTime: 2025-01-20 13:36:10
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/pitch_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></div>
+      <div class="titleCharts">分析分图 :</div>
+      <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
+            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 TwoDMarkersChart from "@/views/performance/components/chartsCom/TwoDMarkersChart.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import {
+  analysisDetail,
+  queryAnalysisedEngine,
+  analysisCommentEdit,
+} from "@/api/performance";
+
 export default {
   name: "pitchPower",
+  components: {
+    DicCard,
+    FilterChart,
+    TwoDMarkersChart,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      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 {
+        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>

+ 19 - 20
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-20 09:19:16
+ * @LastEditTime: 2025-01-20 13:36:42
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/pitch_tsr_cp/index.vue
@@ -278,28 +278,27 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
-
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 19 - 19
src/views/overview/components/power_curve/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:10:08
- * @LastEditTime: 2025-01-17 15:11:04
+ * @LastEditTime: 2025-01-20 13:37:35
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/power_curve/index.vue
@@ -508,27 +508,27 @@ export default {
     padding: 20px;
     flex: 1;
 
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
   .right {
     width: 250px;

+ 20 - 20
src/views/overview/components/power_scatter/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:10:22
- * @LastEditTime: 2025-01-20 09:28:43
+ * @LastEditTime: 2025-01-20 15:45:13
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/power_scatter/index.vue
@@ -40,7 +40,7 @@
       >
         <DDrawingChart
           :key="item.fieldEngineCode"
-          :index="index"
+          :index="index + 'fen'"
           :ref="item.fieldEngineCode"
           :fileAddr="item.fileAddr"
         >
@@ -307,27 +307,27 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 19 - 20
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-20 09:22:44
+ * @LastEditTime: 2025-01-20 13:38:06
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/power_scatter_2D/index.vue
@@ -289,28 +289,27 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
-
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
   .right {
     width: 250px;

+ 22 - 21
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-20 09:19:28
+ * @LastEditTime: 2025-01-20 17:52:54
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/rated_power_windspeed/index.vue
@@ -28,7 +28,7 @@
           </div>
         </template>
         <div style="font-size: 12px; margin-top: 10px">
-在风力发电机组中,额定功率是指风机在特定设计条件下能够安全、有效地输出的最大功率。这个值是基于风机设计和电气系统的能力确定的,通常是在一定的风速下测定,称为额定风速。达到额定风速时,风机可以产生最大的功率输出,而不会超过其机械和电气组件的设计极限。
+          在风力发电机组中,额定功率是指风机在特定设计条件下能够安全、有效地输出的最大功率。这个值是基于风机设计和电气系统的能力确定的,通常是在一定的风速下测定,称为额定风速。达到额定风速时,风机可以产生最大的功率输出,而不会超过其机械和电气组件的设计极限。
         </div>
       </el-alert>
       <div class="titleCharts">分析总图 :</div>
@@ -41,7 +41,7 @@
         <BoxLineCharts
           :key="item.batchCode + index"
           :index="index"
-          :ref="item.batchCode + indChart"
+          :ref="item.batchCode + index"
           :fileAddr="item.fileAddr"
         >
         </BoxLineCharts>
@@ -217,6 +217,7 @@ export default {
         this.diagramRelationsDatas =
           result.data &&
           result.data[0] &&
+          result.data[0].diagramRelations &&
           result.data[0].diagramRelations.filter((item) =>
             item.fileAddr.endsWith(".json")
           );
@@ -282,27 +283,27 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 20 - 20
src/views/overview/components/rated_windspeed/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:08:56
- * @LastEditTime: 2025-01-20 09:23:01
+ * @LastEditTime: 2025-01-20 17:30:51
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/rated_windspeed/index.vue
@@ -41,7 +41,7 @@
       >
         <BarChart
           :key="item.batchCode + index"
-          :inds="index"
+          :inds="index + 'barChart'"
           :ref="item.batchCode"
           :fileAddr="item.fileAddr"
         >
@@ -275,27 +275,27 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 357 - 3
src/views/overview/components/speed_power/index.vue

@@ -1,17 +1,371 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:09:17
- * @LastEditTime: 2025-01-10 09:16:40
+ * @LastEditTime: 2025-01-20 17:16:59
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/speed_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 }"
+      >
+        <DDrawingChart
+          :key="item.batchCode + index"
+          :index="index + 'zong'"
+          :ref="item.batchCode + index"
+          :fileAddr="item.fileAddr"
+        >
+        </DDrawingChart>
+      </VirtualList>
+      <div class="titleCharts">分析分图 :</div>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <TwoDMarkersChart
+          v-if="getFileTypeFromUrl(item.fileAddr) === 'speed_torque'"
+          :index="index + 'TwoDMarkersChart'"
+          :key="item.fieldEngineCode + 'TwoDMarkersChart'"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </TwoDMarkersChart>
+        <DDrawingChart
+          v-if="getFileTypeFromUrl(item.fileAddr) === '3D'"
+          :key="item.fieldEngineCode + 'DDrawingChart'"
+          :index="index + 'fen'"
+          :ref="item.fieldEngineCode + 'DDrawingChart'"
+          :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";
+import TwoDMarkersChart from "@/views/performance/components/chartsCom/TwoDMarkersChart.vue";
+
 export default {
   name: "speedPower",
+  components: {
+    DicCard,
+    FilterChart,
+    DDrawingChart,
+    TinymceEditor,
+    TwoDMarkersChart,
+  },
+  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")
+          ); //总图数据
+        console.log(this.generalFilesDatas, "总图数据");
+
+        if (result.data && result.data[0] && result.data[0].diagramRelations) {
+          // const diagramRelationsDatas = result.data[0].diagramRelations.filter(
+          //   (item) => item.fileAddr.endsWith(".json")
+          // );
+          // this.diagramRelationsDatas2D = diagramRelationsDatas.filter(
+          //   (item) => this.getFileTypeFromUrl(item.fileAddr) === "speed_torque"
+          // );
+          // this.diagramRelationsDatas3D = diagramRelationsDatas.filter(
+          //   (item) => this.getFileTypeFromUrl(item.fileAddr) === "3D"
+          // );
+        }
+        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);
+      }
+    },
+    getFileTypeFromUrl(url) {
+      // 判断文件名或路径是否包含关键字
+      if (url.includes("3D")) {
+        return "3D"; // 如果 URL 中包含 "3D" 字符串,判断为 3D 类型
+      } else if (url.includes("speed_torque")) {
+        return "speed_torque"; // 如果 URL 中包含 "speed_torque" 字符串,判断为 speed_torque 类型
+      } else {
+        return "Unknown"; // 如果都不包含,返回 Unknown 或其他提示
+      }
+    },
+    // 请求风机列表
+    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>

+ 374 - 2
src/views/overview/components/speed_torque/index.vue

@@ -1,9 +1,381 @@
 <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> -->
+      <!-- <div v-for="(item, index) in generalFilesDatas">
+        <DDrawingChart
+          :key="item.batchCode + index"
+          :index="index + 'zong'"
+          :ref="item.batchCode + index"
+          :fileAddr="item.fileAddr"
+        >
+        </DDrawingChart>
+      </div> -->
+
+      <VirtualList
+        :list="generalFilesDatas"
+        keyField="batchCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <DDrawingChart
+          :key="item.batchCode + index"
+          :index="index + 'zong'"
+          :ref="item.batchCode + index"
+          :fileAddr="item.fileAddr"
+        >
+        </DDrawingChart>
+      </VirtualList>
+
+      <!-- <div class="titleCharts">分析分图 :</div> -->
+
+      <VirtualList
+        :list="diagramRelationsDatas2D"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <TwoDMarkersChart
+          :index="index + 'TwoDMarkersChart'"
+          :key="item.fieldEngineCode + 'TwoDMarkersChart'"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </TwoDMarkersChart>
+      </VirtualList>
+      <VirtualList
+        :list="diagramRelationsDatas3D"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <DDrawingChart
+          :key="item.fieldEngineCode + 'DDrawingChart'"
+          :index="index + 'fen'"
+          :ref="item.fieldEngineCode + 'DDrawingChart'"
+          :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";
+import TwoDMarkersChart from "@/views/performance/components/chartsCom/TwoDMarkersChart.vue";
+
 export default {
   name: "speedTorque",
+  components: {
+    DicCard,
+    FilterChart,
+    DDrawingChart,
+    TinymceEditor,
+    TwoDMarkersChart,
+  },
+  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: [],
+      diagramRelationsDatas2D: [],
+      diagramRelationsDatas3D: [],
+    };
+  },
+  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")
+          ); //总图数据
+        console.log(this.generalFilesDatas, "总图数据");
+
+        if (result.data && result.data[0] && result.data[0].diagramRelations) {
+          const diagramRelationsDatas = result.data[0].diagramRelations.filter(
+            (item) => item.fileAddr.endsWith(".json")
+          );
+          this.diagramRelationsDatas2D = diagramRelationsDatas.filter(
+            (item) => this.getFileTypeFromUrl(item.fileAddr) === "speed_torque"
+          );
+          this.diagramRelationsDatas3D = diagramRelationsDatas.filter(
+            (item) => this.getFileTypeFromUrl(item.fileAddr) === "3D"
+          );
+        }
+        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);
+      }
+    },
+    getFileTypeFromUrl(url) {
+      // 判断文件名或路径是否包含关键字
+      if (url.includes("3D")) {
+        return "3D"; // 如果 URL 中包含 "3D" 字符串,判断为 3D 类型
+      } else if (url.includes("speed_torque")) {
+        return "speed_torque"; // 如果 URL 中包含 "speed_torque" 字符串,判断为 speed_torque 类型
+      } else {
+        return "Unknown"; // 如果都不包含,返回 Unknown 或其他提示
+      }
+    },
+    // 请求风机列表
+    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 - 20
src/views/overview/components/temperature_environment/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:09:46
- * @LastEditTime: 2025-01-20 09:19:35
+ * @LastEditTime: 2025-01-20 17:31:10
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/temperature_environment/index.vue
@@ -41,7 +41,7 @@
       >
         <BarChart
           :key="item.batchCode + index"
-          :inds="index"
+          :inds="index + 'barChart'"
           :ref="item.batchCode"
           :fileAddr="item.fileAddr"
         >
@@ -290,27 +290,27 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 10 - 2
src/views/overview/components/temperature_large_components/index.vue

@@ -1,13 +1,21 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:10:00
- * @LastEditTime: 2025-01-10 09:15:34
+ * @LastEditTime: 2025-01-20 13:41:42
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/temperature_large_components/index.vue
 -->
 <template>
-  <div>大部件温度传感器分析</div>
+  <div>
+    大部件温度传感器分析
+    <div class="text">
+      大部件温度分析在风电机组的运维和性能管理中扮演着极为关键的角色。以下是温度分析的几个重要作用:
+      温度是预示机械和电气故障的早期指标之一。通过监测关键部件如齿轮箱、发电机、轴承的温度,可以及时发现异常状况。这种早期检测允许采取预防性措施,从而避免成本高昂的维修和长时间的停机。
+      长期在高温或低温条件下运行可能会加速部件的磨损和老化。通过监控温度并据此调整运行,可以延长风电机组部件的使用寿命。
+      温度分析是实现预测性维护的关键。通过持续监测温度变化和趋势,可以预测何时部件可能会出现问题,从而在故障发生前进行维修或更换,减少意外停机。
+    </div>
+  </div>
 </template>
 <script>
 export default {

+ 297 - 3
src/views/overview/components/tsr/index.vue

@@ -1,17 +1,311 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:10:11
- * @LastEditTime: 2025-01-10 09:15:14
+ * @LastEditTime: 2025-01-20 13:42:18
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/tsr/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"
+        v-if="generalFilesDatas && generalFilesDatas.length > 0"
+      >
+        分析总图 :
+      </div>
+      <div v-for="(item, index) in generalFilesDatas">
+        <lineAndChildLine
+          :key="item.batchCode + index"
+          :index="index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineAndChildLine>
+      </div>
+      <div
+        class="titleCharts"
+        v-if="diagramRelationsDatas && diagramRelationsDatas.length > 0"
+      >
+        分析分图 :
+      </div>
+      <div v-for="(item, index) in diagramRelationsDatas">
+        <lineChartsFen
+          :key="item.fieldEngineCode + index"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fieldEngineCode="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineChartsFen>
+      </div>
+
+      <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 lineChartsFen from "@/views/performance/components/chartsCom/lineChartsFen.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "tsr",
+  components: {
+    DicCard,
+    FilterChart,
+    lineAndChildLine,
+    lineChartsFen,
+    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>

+ 43 - 38
src/views/overview/components/tsr_cp_power/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:10:24
- * @LastEditTime: 2025-01-20 09:23:09
+ * @LastEditTime: 2025-01-20 13:42:45
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/tsr_cp_power/index.vue
@@ -28,40 +28,43 @@
           </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 }"
+      <div
+        class="titleCharts"
+        v-if="generalFilesDatas && generalFilesDatas.length > 0"
       >
+        分析总图 :
+      </div>
+      <div v-for="(item, index) in generalFilesDatas">
         <lineAndChildLine
           :key="item.batchCode + index"
-          :inds="index"
+          :index="index"
           :ref="item.batchCode"
           :fileAddr="item.fileAddr"
         >
         </lineAndChildLine>
-      </VirtualList>
-      <div class="titleCharts">分析分图 :</div>
-      <VirtualList
-        :list="diagramRelationsDatas"
-        keyField="fieldEngineCode"
-        :itemSize="452"
-        v-slot="{ item, index }"
+      </div>
+      <div
+        class="titleCharts"
+        v-if="diagramRelationsDatas && diagramRelationsDatas.length > 0"
       >
-        <lineAndChildLine
+        分析分图 :
+      </div>
+      <div v-for="(item, index) in diagramRelationsDatas">
+        <lineChartsFen
           :key="item.fieldEngineCode + index"
-          :inds="index"
+          :index="index"
           :ref="item.fieldEngineCode"
+          :fieldEngineCode="item.fieldEngineCode"
           :fileAddr="item.fileAddr"
         >
-        </lineAndChildLine>
-      </VirtualList>
+        </lineChartsFen>
+      </div>
+
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -95,6 +98,7 @@
 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 lineChartsFen from "@/views/performance/components/chartsCom/lineChartsFen.vue";
 import TinymceEditor from "@/components/Tinymce.vue";
 import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
 
@@ -104,6 +108,7 @@ export default {
     DicCard,
     FilterChart,
     lineAndChildLine,
+    lineChartsFen,
     TinymceEditor,
   },
   props: {
@@ -290,27 +295,27 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 21 - 20
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-20 09:19:44
+ * @LastEditTime: 2025-01-20 13:43:15
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/index.vue
@@ -28,7 +28,8 @@
           </div>
         </template>
         <div style="font-size: 12px; margin-top: 10px">
-          此项分析是基于叶尖速比和三次根号下风能利用系数的比值,是机组除去风速影响以外的本身运行特性的展示,对于判断如何优化机组至关重要:该分析也是监测风机性能的重要手段。如果该值出现异常趋势,可能预示着设备损耗、叶片故障等异常状态。通过分析运行数据,可以调整风机设计和操作策略,以保持理想的运行状态,从而优化整体性能和延长风机的使用寿命。
+          此项分析是基于叶尖速比和三次根号下风能利用系数的比值,是机组除去风速影响以外的本身运行特性的展示,对于判断如何优化机组至关重要:
+          该分析也是监测风机性能的重要手段。如果该值出现异常趋势,可能预示着设备损耗、叶片故障等异常状态。通过分析运行数据,可以调整风机设计和操作策略,以保持理想的运行状态,从而优化整体性能和延长风机的使用寿命。
         </div>
       </el-alert>
       <VirtualList
@@ -279,27 +280,27 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 18 - 22
src/views/overview/components/tsr_trend/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:10:39
- * @LastEditTime: 2025-01-16 17:43:47
+ * @LastEditTime: 2025-01-20 13:43:40
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/tsr_trend/index.vue
@@ -28,10 +28,7 @@
           </div>
         </template>
         <div style="font-size: 12px; margin-top: 10px">
-          分析风力发电机组的Cp值对于优化其性能和增强效率至关重要:通过测量和分析Cp,可以直观了解风机的效率。Cp值越接近贝兹极限,说明风机的设计和运行越高效。
-        </div>
-        <div style="font-size: 12px; margin-top: 10px">
-          Cp的分析也是监测风机性能的重要手段。如果Cp值出现异常下降,可能预示着机械故障、叶片磨损或其他维护需求。
+          叶尖速比的分析对于理解和优化风力发电机组的性能至关重要:叶尖速比直接影响风轮的空气动力学效率。一个合适的叶尖速比可以确保风轮以最高效率捕获风能。过高的叶尖速比可能会导致叶片承受过大的离心力和动态压力,从而增加机械负荷。通过监测和调整叶尖速比,可以防止过度磨损和损坏。
         </div>
       </el-alert>
       <VirtualList
@@ -285,26 +282,25 @@ export default {
     padding: 20px;
     flex: 1;
     &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
-
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 297 - 3
src/views/overview/components/tsr_windspeed/index.vue

@@ -1,17 +1,311 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:10:59
- * @LastEditTime: 2025-01-10 09:14:00
+ * @LastEditTime: 2025-01-20 13:43:58
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/tsr_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"
+        v-if="generalFilesDatas && generalFilesDatas.length > 0"
+      >
+        分析总图 :
+      </div>
+      <div v-for="(item, index) in generalFilesDatas">
+        <lineAndChildLine
+          :key="item.batchCode + index"
+          :index="index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineAndChildLine>
+      </div>
+      <div
+        class="titleCharts"
+        v-if="diagramRelationsDatas && diagramRelationsDatas.length > 0"
+      >
+        分析分图 :
+      </div>
+      <div v-for="(item, index) in diagramRelationsDatas">
+        <lineChartsFen
+          :key="item.fieldEngineCode + index"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fieldEngineCode="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineChartsFen>
+      </div>
+
+      <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 lineChartsFen from "@/views/performance/components/chartsCom/lineChartsFen.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "tsrWindspeed",
+  components: {
+    DicCard,
+    FilterChart,
+    lineAndChildLine,
+    lineChartsFen,
+    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>

+ 20 - 21
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-20 09:19:52
+ * @LastEditTime: 2025-01-20 17:31:50
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/wind_spee/index.vue
@@ -41,7 +41,7 @@
       >
         <BarChart
           :key="item.batchCode + index"
-          :inds="index"
+          :inds="index + 'barChart'"
           :ref="item.batchCode"
           :fileAddr="item.fileAddr"
         ></BarChart>
@@ -274,28 +274,27 @@ export default {
     padding: 20px;
     flex: 1;
 
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
-
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
   .right {
     width: 250px;

+ 20 - 22
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-20 09:21:34
+ * @LastEditTime: 2025-01-20 17:32:09
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/wind_speed_frequency/index.vue
@@ -39,7 +39,7 @@
       >
         <BarChart
           :key="item.fieldEngineCode + index"
-          :inds="index"
+          :inds="index + 'barChart'"
           :ref="item.fieldEngineCode"
           :fileAddr="item.fileAddr"
         ></BarChart>
@@ -287,29 +287,27 @@ export default {
     padding: 20px;
     flex: 1;
 
-  /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
-
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
-
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
   .right {
     width: 250px;

+ 19 - 19
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-20 09:23:35
+ * @LastEditTime: 2025-01-20 13:44:27
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/yaw_error_density/index.vue
@@ -288,27 +288,27 @@ export default {
     overflow: auto;
     padding: 20px;
     flex: 1;
-      /* 滚动条整体样式 */
-  &::-webkit-scrollbar {
-    width: 6px; /* 滚动条宽度 */
-  }
+    /* 滚动条整体样式 */
+    &::-webkit-scrollbar {
+      width: 6px; /* 滚动条宽度 */
+    }
 
-  /* 滚动条轨道 */
-  &::-webkit-scrollbar-track {
-    background: #f5f7fa;
-    border-radius: 3px;
-  }
+    /* 滚动条轨道 */
+    &::-webkit-scrollbar-track {
+      background: #f5f7fa;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块 */
-  &::-webkit-scrollbar-thumb {
-    background: #c0c4cc;
-    border-radius: 3px;
-  }
+    /* 滚动条滑块 */
+    &::-webkit-scrollbar-thumb {
+      background: #c0c4cc;
+      border-radius: 3px;
+    }
 
-  /* 滚动条滑块悬停时 */
-  &::-webkit-scrollbar-thumb:hover {
-    background: #909399;
-  }
+    /* 滚动条滑块悬停时 */
+    &::-webkit-scrollbar-thumb:hover {
+      background: #909399;
+    }
   }
 
   .right {

+ 2 - 2
src/views/performance/components/EditAnalysis.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-05-29 09:14:23
- * @LastEditTime: 2025-01-14 10:39:56
+ * @LastEditTime: 2025-01-20 16:47:34
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/EditAnalysis.vue
@@ -11,7 +11,7 @@
   <div v-loading="loading">
     <el-form ref="form" :model="form" label-width="120px">
       <el-collapse v-model="activeNames">
-        <el-collapse-item title="基础筛选:" name="1">
+        <el-collapse-item title="数据关联:" name="1">
           <el-row class="flex-wrap-row" :gutter="5">
             <el-col :xs="24" :sm="24" :md="12" :lg="8" :xl="5">
               <el-form-item label="分析类型" prop="configAnalysis">

+ 2 - 2
src/views/performance/components/analysisEvent.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-05-29 09:13:51
- * @LastEditTime: 2025-01-10 16:04:27
+ * @LastEditTime: 2025-01-20 16:47:46
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/analysisEvent.vue
@@ -33,7 +33,7 @@
         </el-col>
       </el-row>
       <el-collapse v-model="activeNames">
-        <el-collapse-item title="基础筛选:" name="1">
+        <el-collapse-item title="数据关联:" name="1">
           <el-row class="flex-wrap-row" :gutter="5">
             <el-col :xs="24" :sm="24" :md="12" :lg="8" :xl="5">
               <el-form-item

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

@@ -1,16 +1,21 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-17 19:04:52
- * @LastEditTime: 2025-01-20 09:37:15
+ * @LastEditTime: 2025-01-20 16:27:38
  * @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>
+  <div style="height: 452px">
+    <div
+      :id="`plotly-3d-chart-` + index"
+      style="width: 100%; height: 400px"
+    ></div>
+    <div v-loading="loading" ref="plotlyChart" style="height: 400px">
+      <el-empty v-if="isError" description="请求失败"></el-empty>
+    </div>
+  </div>
 </template>
 
 <script>
@@ -25,7 +30,7 @@ export default {
     },
     index: {
       default: "",
-      type: Number,
+      type: String,
     },
   },
   data() {
@@ -102,11 +107,15 @@ export default {
         try {
           this.loading = true;
           this.cancelToken = axios.CancelToken.source();
-          console.log(this.cancelToken);
+          console.log(this.fileAddr, "3D url");
           const resultChartsData = await axios.get(this.fileAddr, {
             cancelToken: this.cancelToken.token,
           });
-          console.log(resultChartsData);
+          // console.log(
+          //   resultChartsData.data,
+          //   JSON.parse(resultChartsData.data),
+          //   "解析3D数据"
+          // );
           this.chartData = resultChartsData.data;
           this.renderChart();
           this.isError = false;

+ 2 - 2
src/views/performance/components/chartsCom/BarChart.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-09-11 14:30:17
- * @LastEditTime: 2025-01-20 09:16:32
+ * @LastEditTime: 2025-01-20 17:31:39
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/BarChart.vue
@@ -51,7 +51,7 @@ export default {
       type: String,
     },
     inds: {
-      type: Number,
+      type: String,
       default() {
         return 0;
       },

+ 12 - 8
src/views/performance/components/chartsCom/BoxLineCharts.vue

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

+ 177 - 50
src/views/performance/components/chartsCom/HeatmapCharts.vue

@@ -1,22 +1,13 @@
-<!--
- * @Author: your name
- * @Date: 2024-09-11 14:29:26
- * @LastEditTime: 2025-01-13 15:12:38
- * @LastEditors: bogon
- * @Description: In User Settings Edit
- * @FilePath: /performance-test/src/views/performance/components/chartsCom/HeatmapCharts.vue
--->
 <template>
   <div>
-    <!-- HeatmapCharts
-    <h1>分钟级SCADA数据记录完整度分析</h1>
-    <h1>秒级SCADA数据记录完整度分析</h1> -->
-    <div :id="`chart-${inds}`" style="width: 100%; height: 550px"></div>
+    <div :id="`chart-${inds}`" style="width: 100%; height: 450px"></div>
   </div>
 </template>
 <script>
+import { nextTick } from "vue"; // 导入 nextTick
 import { allTypesDatas } from "@/utils/allTypesOfAnalysisData.js";
 import Plotly from "plotly.js-dist";
+import axios from "axios";
 export default {
   props: {
     inds: {
@@ -25,26 +16,103 @@ export default {
         return 0;
       },
     },
+    fileAddr: {
+      type: String,
+      default: "",
+    },
   },
   data() {
     return {
+      chartData: {},
       initData: [
         {
           z: [
-            [100, 95, 20, 7, 75, 100],
-            [0, 50, 0, 0, 0, 0],
-            [100, 74, 7, 95, 100, 100],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
+            [
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+              5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+            ],
           ],
           x: [
-            "#2024-01",
-            "#2024-02",
-            "#2024-03",
-            "#2024-04",
-            "#2024-05",
-            "#2024-06",
+            "#01",
+            "#02",
+            "#03",
+            "#04",
+            "#05",
+            "#06",
+            "#07",
+            "#08",
+            "#09",
+            "#10",
+            "#11",
+            "#12",
+            "#13",
+            "#14",
+            "#15",
+            "#16",
+            "#17",
+            "#18",
+            "#19",
+            "#20",
+            "#21",
+          ],
+          y: [
+            "2023-01",
+            "2023-02",
+            "2023-03",
+            "2023-04",
+            "2023-05",
+            "2023-06",
+            "2023-07",
+            "2023-08",
+            "2023-09",
+            "2023-10",
+            "2023-11",
+            "2023-12",
           ],
-          y: ["Morning", "Afternoon", "Evening"],
-          // y: ["Morning", "Afternoon"],
           type: "heatmap",
           colorscale: "Viridis", //分钟scads
           colorscale: [
@@ -62,63 +130,122 @@ export default {
     };
   },
   mounted() {
-    this.initcharts();
+    this.getData();
+    if (this.fileAddr) {
+      this.getData();
+    }
   },
+
   methods: {
+    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;
+          this.initData[0].y = resultChartsData.data[0].xData;
+          this.initData[0].z = resultChartsData.data[0].yData;
+          // 使用 nextTick 来确保 DOM 渲染完成后绘制图表
+          nextTick(() => {
+            this.initcharts();
+            // this.isError = false;
+            // this.loading = false;
+          });
+        } catch (error) {
+          console.error("Error loading data:", error);
+          this.isError = true;
+          this.loading = false;
+        }
+      }
+    },
     initcharts() {
       const lineDatas = allTypesDatas.filter(
         (item) =>
           item.analysisTypeCode === "data_integrity_second" ||
           item.analysisTypeCode === "data_integrity_minute"
       )[0];
+
+      // 生成 annotations 数据
+
       const layout = {
         ...lineDatas.lableConfig,
         showlegend: false,
         shapes: this.createShapesBorder(
           this.initData[0].y.length,
-          this.initData[0].x.length,
+          this.initData[0].x.length + 1,
           1,
           "white",
           0
-        ), // 添加边框
+        ),
+        // annotations: this.createAnnotations(this.initData[0].z),
         margin: {
-          l: 100, // 左侧边距,单位是像素
-          r: 100, // 右侧边距,单位是像素
-          t: 100, // 上方边距,单位是像素
-          b: 100, // 下方边距,单位是像素
+          l: 100,
+          r: 100,
+          t: 100,
+          b: 100,
+        },
+        autosize: true,
+        yaxis: {
+          type: "category",
+          tickvals: this.initData[0].y, // 确保 Y 轴的值和你的数据匹配
+          ticktext: this.initData[0].y,
+          showticks: false,
+          showgrid: true,
+        },
+        xaxis: {
+          tickvals: this.initData[0].x,
+          ticktext: this.initData[0].x,
+          showticks: false,
+          showgrid: true,
         },
-        autosize: true, // 开启自适应
+        plot_bgcolor: "white", // 背景颜色设置为白色,确保背景和网格线一致
+        gridcolor: "#d3d3d3", // 设置网格线颜色
       };
-      // 添加注释
-      for (var i = 0; i < this.initData[0].y.length; i++) {
-        for (var j = 0; j < this.initData[0].x.length; j++) {
-          const value = this.initData[0].z[i][j];
-          const fontColor = value < 50 ? "#434443" : "white"; // 根据 z 值判断字体颜色
-          var result = {
-            xref: "x",
-            yref: "y",
-            x: this.initData[0].x[j],
-            y: this.initData[0].y[i],
-            text: this.initData[0].z[i][j],
-            font: { size: 12, color: fontColor },
-            showarrow: false,
-          };
-          layout.annotations.push(result);
-        }
-      }
       Plotly.newPlot(`chart-${this.inds}`, this.initData, layout, {
         responsive: true,
       });
     },
+    // createAnnotations(zData) {
+    //   const annotations = [];
+    //   for (let row = 0; row < zData.length; row++) {
+    //     for (let col = 0; col < zData[row].length; col++) {
+    //       const x = this.initData[0].x[col];
+    //       const y = this.initData[0].y[row];
+    //       const value = zData[row][col];
+
+    //       // 打印 x, y, 和 value 检查是否为 NaN 或无效值
+    //       console.log(`x: ${x}, y: ${y}, value: ${value}`);
+
+    //       if (!isNaN(value)) {
+    //         annotations.push({
+    //           x: x,
+    //           y: y,
+    //           text: value.toString(),
+    //           showarrow: false,
+    //           font: {
+    //             size: 10,
+    //             color: "black",
+    //           },
+    //           align: "center",
+    //         });
+    //       }
+    //     }
+    //   }
+    //   return annotations;
+    // },
+
     createShapesBorder(rows, cols, borderWidth, borderColor, offset) {
       var shapes = [];
       for (var row = 0; row < rows; row++) {
         for (var col = 0; col < cols; col++) {
           shapes.push({
             type: "rect",
-            x0: col - 0.5 - offset,
+            x0: col - 0.5 + offset,
             x1: col + 0.5 + offset,
-            y0: row - 0.5 - offset,
+            y0: row - 0.5 + offset,
             y1: row + 0.5 + offset,
             line: {
               color: borderColor,

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

@@ -20,9 +20,6 @@
           <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'"> -->

+ 82 - 73
src/views/performance/components/chartsCom/lineAndChildLine.vue

@@ -1,31 +1,16 @@
-<!--
- * @Author: your name
- * @Date: 2024-09-11 14:28:15
- * @LastEditTime: 2024-09-11 14:40:37
- * @LastEditors: milo-MacBook-Pro.local
- * @Description: In User Settings Edit
- * @FilePath: /performance-test/src/views/performance/components/chartsCom/lineAndChildLine.vue
--->
-<!-- <template>
-  <div>
-    lineAndChildLine
-    <h1>有功功率曲线分析</h1>
-    <h1>叶尖速比和有功功率分析</h1>
-    <h1>叶尖速比-Cp-功率分析</h1>
-    <h1>风能利用系数和有功功率分析</h1>
-    <h1>风能利用系数和风速分析</h1>
-    <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>
+      <!-- <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> -->
       <div>
         <el-button size="small" @click="toggleChartType">
           切换为{{ chartType === "line" ? "柱状图" : "折线图" }}
@@ -34,7 +19,11 @@
     </div>
 
     <!-- 图表容器 -->
-    <div v-loading="loading" :id="`bar-chart${inds}`" style="width: 100%; height: 400px">
+    <div
+      v-loading="loading"
+      :id="`bar-chart${index}`"
+      style="width: 100%; height: 400px"
+    >
       <el-empty v-if="isError" description="请求失败"></el-empty>
     </div>
   </div>
@@ -52,7 +41,7 @@ export default {
       type: String,
       default: "",
     },
-    inds: {
+    index: {
       type: Number,
       default() {
         return 0;
@@ -62,31 +51,31 @@ export default {
   mixins: [myMixin],
   data() {
     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",
-          },
-        ],
-      },
+      chartData: {},
       chartType: "line", // 默认图表类型是折线图
       color1: "#406DAB", // 默认颜色
       loading: false,
       isError: false,
+      colors: [
+        "#DFEDC1",
+        "#DBEEBC",
+        "#A8D7BE",
+        "#8ECAC1",
+        "#77BDC2",
+        "#64ADC2",
+        "#559ABE",
+        "#4884B7",
+        "#406DAB",
+        "#3856A0",
+        "#314291",
+        "#28357A",
+        "#1A285E",
+      ],
     };
   },
   mounted() {
     if (this.fileAddr) {
       this.getData();
-    } else {
-      this.drawChart(); // 如果没有文件地址,直接绘制模拟数据
     }
   },
   methods: {
@@ -96,10 +85,10 @@ export default {
         try {
           this.loading = true;
           this.cancelToken = axios.CancelToken.source();
-          // const resultChartsData = await axios.get(this.fileAddr, {
-          //   cancelToken: this.cancelToken.token,
-          // });
-          // this.chartData = resultChartsData.data;
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token,
+          });
+          this.chartData = resultChartsData.data;
           // 使用 nextTick 来确保 DOM 渲染完成后绘制图表
           nextTick(() => {
             this.drawChart();
@@ -115,22 +104,29 @@ export default {
     },
     // 绘制图表
     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 data = [];
+      this.chartData.data.forEach((turbine, index) => {
+        // 判断图表类型,根据类型调整绘制方式
+        const chartConfig = {
+          x: turbine.xData, // X 数据
+          y: turbine.yData, // Y 数据
+          name: turbine.engineName, // 使用机组名称
+          line: {
+            color: this.colors[index % this.colors.length], // 为每个机组分配不同的颜色
+          },
+        };
+
+        if (this.chartType === "line") {
+          chartConfig.mode = "lines"; // 如果是折线图
+        } else if (this.chartType === "bar") {
+          chartConfig.type = "bar"; // 如果是柱状图
+        }
+
+        data.push(chartConfig);
+      });
 
       const layout = {
-        title: this.chartData.analysisTypeCode || "图表", // 图表标题
+        title: this.chartData.title,
         xaxis: {
           title: this.chartData.xaixs || "X轴", // 横坐标标题
         },
@@ -144,26 +140,39 @@ export default {
           b: 50,
         },
         autosize: true, // 开启自适应
+        barmode: this.chartType === "bar" ? "stack" : "group", // 如果是柱状图则启用堆叠
       };
-
-      // 渲染图表
-      Plotly.newPlot(
-        `bar-chart${this.inds}`,
-        [trace,trace],
-        layout,
-        {
-          responsive: true,
-        }
-      );
+      if (
+        this.chartData.contract_Cp_curve_yData &&
+        this.chartData.contract_Cp_curve_yData.length > 0
+      ) {
+        data.push({
+          x: this.chartData.contract_Cp_curve_xData,
+          y: this.chartData.contract_Cp_curve_yData,
+          mode: "lines+markers",
+          name: "合同功率曲线",
+          line: {
+            color: "red",
+            width: 1, // 设置线条的宽度为1
+          },
+          marker: { color: "red", size: 4 },
+        });
+      }
+      // 使用 Plotly.react 来更新图表
+      Plotly.react(`bar-chart${this.index}`, data, layout, {
+        responsive: true,
+      });
     },
+
     // 切换图表类型
     toggleChartType() {
-      this.chartType = this.chartType === "line" ? "bar" : "line";
-      this.drawChart();
+      this.chartType = this.chartType === "line" ? "bar" : "line"; // 切换图表类型
+      this.drawChart(); // 重新绘制图表
     },
+
     // 更新图表颜色
     updateChartColor() {
-      this.drawChart();
+      this.drawChart(); // 更新颜色后重新绘制图表
     },
   },
 };

+ 205 - 0
src/views/performance/components/chartsCom/lineChartsFen.vue

@@ -0,0 +1,205 @@
+<!--
+ * @Author: your name
+ * @Date: 2025-01-20 11:41:41
+ * @LastEditTime: 2025-01-20 14:21:32
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/chartsCom/lineChartsFen.vue
+-->
+<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="`line-chart-fen-${index}`"
+      style="width: 100%; height: 400px"
+    >
+      <el-empty v-if="isError" description="请求失败"></el-empty>
+    </div>
+  </div>
+</template>
+
+<script>
+import { nextTick } from "vue"; // 导入 nextTick
+import Plotly from "plotly.js-dist";
+import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin"; // 假设你需要的 mixin
+
+export default {
+  props: {
+    fileAddr: {
+      type: String,
+      default: "",
+    },
+    index: {
+      type: Number,
+      default() {
+        return 0;
+      },
+    },
+    fieldEngineCode: {
+      type: String,
+      default: "",
+    },
+  },
+  mixins: [myMixin],
+  data() {
+    return {
+      chartData: {},
+      chartType: "line", // 默认图表类型是折线图
+      color1: "#406DAB", // 默认颜色
+      loading: false,
+      isError: false,
+    };
+  },
+  mounted() {
+    if (this.fileAddr) {
+      this.getData();
+    }
+  },
+  methods: {
+    // 获取数据
+    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 sortedData = this.chartData.data.sort((a, b) => {
+        // 符合条件的数据排在前面
+        if (
+          a.engineCode === this.fieldEngineCode &&
+          b.engineCode !== this.fieldEngineCode
+        ) {
+          return 1; // a 排在前面
+        }
+        if (
+          a.engineCode !== this.fieldEngineCode &&
+          b.engineCode === this.fieldEngineCode
+        ) {
+          return -1; // b 排在前面
+        }
+        return 0; // 如果两者都符合或都不符合,保持原顺序
+      });
+
+      const data = [];
+      const lineData = []; // 用于存储所有线图数据
+
+      sortedData.forEach((turbine, index) => {
+        // 判断当前机组的 engineCode 是否与 fieldEngineCode 匹配
+        const color =
+          turbine.engineCode === this.fieldEngineCode ? this.color1 : "#D3D3D3"; // #D3D3D3 为灰色
+
+        const chartConfig = {
+          x: turbine.xData, // X 数据
+          y: turbine.yData, // Y 数据
+          name: turbine.engineName, // 使用机组名称
+          line: { color }, // 设置线条颜色
+          marker: { color }, // 设置柱状图的颜色
+        };
+
+        // 判断是否为线图
+        if (this.chartType === "line") {
+          chartConfig.mode = "lines"; // 如果是折线图
+          lineData.push(chartConfig); // 将线图数据存储到 lineData 中
+        } else if (this.chartType === "bar") {
+          chartConfig.type = "bar"; // 如果是柱状图
+          data.push(chartConfig); // 将柱状图数据存储到 data 中
+        }
+      });
+
+      // 将非线图的数据放到前面,线图的数据放到最后
+      const finalData = [...data, ...lineData]; // 先放柱状图,再放线图
+      if (
+        this.chartData.contract_Cp_curve_yData &&
+        this.chartData.contract_Cp_curve_yData.length > 0
+      ) {
+        finalData.push({
+          x: this.chartData.contract_Cp_curve_xData,
+          y: this.chartData.contract_Cp_curve_yData,
+          mode: "lines+markers",
+          name: "合同功率曲线",
+          line: {
+            color: "red",
+            width: 1, // 设置线条的宽度为1
+          },
+          marker: { color: "red", size: 4 },
+        });
+      }
+      const layout = {
+        title: this.chartData.title || "图表",
+        xaxis: {
+          title: this.chartData.xaixs || "X轴", // 横坐标标题
+        },
+        yaxis: {
+          title: this.chartData.yaixs || "Y轴", // 纵坐标标题
+        },
+        margin: {
+          l: 50,
+          r: 50,
+          t: 50,
+          b: 50,
+        },
+        autosize: true, // 开启自适应
+        barmode: this.chartType === "bar" ? "stack" : "group", // 如果是柱状图则启用堆叠
+      };
+
+      // 使用 Plotly.react 来更新图表
+      Plotly.react(`line-chart-fen-${this.index}`, finalData, layout, {
+        responsive: true,
+      });
+    },
+    // 切换图表类型
+    toggleChartType() {
+      this.chartType = this.chartType === "line" ? "bar" : "line"; // 切换图表类型
+      this.drawChart(); // 重新绘制图表
+    },
+
+    // 更新图表颜色
+    updateChartColor() {
+      this.drawChart(); // 更新颜色后重新绘制图表
+    },
+  },
+};
+</script>
+
+<style scoped>
+/* 样式可以根据需求自定义 */
+</style>

+ 3 - 3
src/views/performance/editAssets.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-05-27 09:26:31
- * @LastEditTime: 2025-01-14 13:29:47
+ * @LastEditTime: 2025-01-20 13:59:16
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/editAssets.vue
@@ -24,9 +24,9 @@
       <el-tab-pane label="分析事件" name="first">
         <analysis-event :activeName="activeName"></analysis-event>
       </el-tab-pane>
-      <el-tab-pane label="分析编辑" name="second">
+      <!-- <el-tab-pane label="分析编辑" name="second">
         <edit-analysis :activeName="activeName"></edit-analysis>
-      </el-tab-pane>
+      </el-tab-pane> -->
     </el-tabs>
   </div>
 </template>

BIN
归档.zip