Browse Source

各环境区分配置

liujiejie 21 hours ago
parent
commit
de1dad8325

+ 24 - 22
.env.demo

@@ -1,8 +1,8 @@
 ###
  # @Author: your name
  # @Date: 2025-07-17 15:36:25
- # @LastEditTime: 2025-07-25 09:32:54
- # @LastEditors: bogon
+ # @LastEditTime: 2025-07-30 09:40:51
+ # @LastEditors: milo-MacBook-Pro.local
  # @Description: In User Settings Edit
  # @FilePath: /performance-test/.env.demo
 ### 
@@ -14,25 +14,27 @@ VUE_APP_ISSHOWHD='default'
 
 VUE_APP_TITLE='机组功率曲线异常检测数据分析系统'
 #外网
-# VUE_APP_MAPVIEW=http://106.120.102.238:18000/tiles/{z}/{x}/{y}.png
-# VUE_APP_UPLOAD="http://106.120.102.238:18998/api/energy-manage-service/api/check/upload"
-# VUE_APP_APIPROXY='http://106.120.102.238:18998/api'
-# VUE_APP_WZLAPIPROXY='http://106.120.102.238:18998/transDataWeb'
-# VUE_APP_ETLAPIPROXY='http://106.120.102.238:18998/transDataWeb'
-# VUE_APP_AnalysisMultiAPIPROXY='http://106.120.102.238:18998/AnalysisMulti'
-# #自定义算法文佳 目前无法使用,可能是服务未启动
-# VUE_APP_sAlgorithmAPIPROXY='http://106.120.102.238:18998/AnalysisMulti'
-# VUE_APP_databaseApiAPIPROXY='http://106.120.102.238:18998/databaseApi'
-# VUE_APP_downLoadChartAPIPROXY='http://106.120.102.238:18998/downLoadChart'
+#VUE_APP_MAPVIEW=http://106.120.102.238:18998/tiles/{z}/{x}/{y}.png
+VUE_APP_MAPVIEW=/tiles/{z}/{x}/{y}.png
+VUE_APP_UPLOAD="http://106.120.102.238:18998/api/energy-manage-service/api/check/upload"
+VUE_APP_APIPROXY='http://106.120.102.238:18998/api'
+VUE_APP_WZLAPIPROXY='http://106.120.102.238:18998/transDataWeb'
+VUE_APP_ETLAPIPROXY='http://106.120.102.238:18998/transDataWeb'
+VUE_APP_AnalysisMultiAPIPROXY='http://106.120.102.238:18998/AnalysisMulti'
+#自定义算法文佳 目前无法使用,可能是服务未启动
+VUE_APP_sAlgorithmAPIPROXY='http://106.120.102.238:18998/sAlgorithm'
+VUE_APP_databaseApiAPIPROXY='http://106.120.102.238:18998/databaseApi'
+VUE_APP_downLoadChartAPIPROXY='http://106.120.102.238:18998/downLoadChart'
 
 #内网
-VUE_APP_UPLOAD="http://192.168.50.235/energy-manage-service/api/check/upload"
-VUE_APP_MAPVIEW=http://192.168.50.235/tiles/{z}/{x}/{y}.png
-VUE_APP_APIPROXY='http://192.168.50.235:16600'
-VUE_APP_WZLAPIPROXY='http://192.168.50.235:8998/transDataWeb'
-VUE_APP_ETLAPIPROXY='http://192.168.50.235:8998/transDataWeb'
-VUE_APP_AnalysisMultiAPIPROXY='http://192.168.50.235:8998/AnalysisMulti'
-# #自定义算法文佳 目前无法使用,可能是服务未启动
-VUE_APP_sAlgorithmAPIPROXY='http://192.168.50.235:8998/AnalysisMulti'
-VUE_APP_databaseApiAPIPROXY='http://192.168.50.234:3002'
-VUE_APP_downLoadChartAPIPROXY='http://192.168.50.235:8999/downLoadChart'
+# VUE_APP_UPLOAD="http://192.168.50.235/energy-manage-service/api/check/upload"
+# VUE_APP_MAPVIEW=/tiles/{z}/{x}/{y}.png
+# # VUE_APP_MAPVIEW=http://192.168.50.235/tiles/{z}/{x}/{y}.png
+# VUE_APP_APIPROXY='http://192.168.50.235:16600'
+# VUE_APP_WZLAPIPROXY='http://192.168.50.235:8998/transDataWeb'
+# VUE_APP_ETLAPIPROXY='http://192.168.50.235:8998/transDataWeb'
+# VUE_APP_AnalysisMultiAPIPROXY='http://192.168.50.235:8998/AnalysisMulti'
+# # #自定义算法文佳 目前无法使用,可能是服务未启动
+# VUE_APP_sAlgorithmAPIPROXY='http://192.168.50.235:8998/sAlgorithm'
+# VUE_APP_databaseApiAPIPROXY='http://192.168.50.234:3002'
+# VUE_APP_downLoadChartAPIPROXY='http://192.168.50.235:8999/downLoadChart'

+ 24 - 24
.env.dev

@@ -1,7 +1,7 @@
 ###
  # @Author: your name
  # @Date: 2025-07-17 14:14:27
- # @LastEditTime: 2025-07-22 13:58:52
+ # @LastEditTime: 2025-07-30 09:49:16
  # @LastEditors: milo-MacBook-Pro.local
  # @Description: In User Settings Edit
  # @FilePath: /performance-test/.env.dev
@@ -12,28 +12,28 @@ VUE_APP_ISSHOWHD='default'
 VUE_APP_TITLE='机组功率曲线异常检测数据分析系统'
 
 #外网
-VUE_APP_MAPVIEW=http://106.120.102.238:18000/tiles/{z}/{x}/{y}.png
-VUE_APP_UPLOAD="http://106.120.102.238:16700/energy-manage-service/api/check/upload"
-VUE_APP_APIPROXY='http://106.120.102.238:16700'
-VUE_APP_WZLAPIPROXY='http://106.120.102.238:18080/WindTransDev'
-VUE_APP_ETLAPIPROXY='http://106.120.102.238:18080/WindTransDev'
-VUE_APP_AnalysisMultiAPIPROXY='http://106.120.102.238:28999/AnalysisMulti'
-#自定义算法文佳 目前无法使用,可能是服务未启动
-VUE_APP_sAlgorithmAPIPROXY='http://106.120.102.238:58880'
-VUE_APP_databaseApiAPIPROXY='http://106.120.102.238:58880'
-# #暂时不知下载报告内网dev 环境地址
-VUE_APP_downLoadChartAPIPROXY='http://106.120.102.238:58880'
+# VUE_APP_MAPVIEW=/tiles/{z}/{x}/{y}.png
+# VUE_APP_UPLOAD="http://106.120.102.238:16700/energy-manage-service/api/check/upload"
+# VUE_APP_APIPROXY='http://106.120.102.238:16700'
+# VUE_APP_WZLAPIPROXY='http://106.120.102.238:18080/WindTransDev'
+# VUE_APP_ETLAPIPROXY='http://106.120.102.238:18080/WindTransDev'
+# VUE_APP_AnalysisMultiAPIPROXY='http://106.120.102.238:28999/AnalysisMulti'
+# #自定义算法文佳 目前无法使用,可能是服务未启动
+# VUE_APP_sAlgorithmAPIPROXY='http://106.120.102.238:58880'
+# VUE_APP_databaseApiAPIPROXY='http://106.120.102.238:58880'
+# # #暂时不知下载报告内网dev 环境地址
+# VUE_APP_downLoadChartAPIPROXY='http://106.120.102.238:58880'
 
 #内网
-# VUE_APP_UPLOAD="http://192.168.50.235/energy-manage-service/api/check/upload"
-# VUE_APP_MAPVIEW=http://192.168.50.235/tiles/{z}/{x}/{y}.png
-# VUE_APP_APIPROXY='http://192.168.50.235:16200'
-# VUE_APP_WZLAPIPROXY='http://192.168.50.241:9001'
-# VUE_APP_ETLAPIPROXY='http://192.168.50.241:9001'
-# # #自定义算法文佳 目前无法使用,可能是服务未启动
-# VUE_APP_sAlgorithmAPIPROXY='http://192.168.50.235:8666'
-# VUE_APP_databaseApiAPIPROXY='http://192.168.50.234:3002'
-# #暂时不知健康评估内网dev 环境地址
-# VUE_APP_AnalysisMultiAPIPROXY=''
-# #暂时不知下载报告内网dev 环境地址
-# VUE_APP_downLoadChartAPIPROXY=''
+VUE_APP_UPLOAD="http://192.168.50.235/energy-manage-service/api/check/upload"
+VUE_APP_MAPVIEW=/tiles/{z}/{x}/{y}.png
+VUE_APP_APIPROXY='http://192.168.50.235:16200'
+VUE_APP_WZLAPIPROXY='http://192.168.50.241:9001'
+VUE_APP_ETLAPIPROXY='http://192.168.50.241:9001'
+# #自定义算法文佳 目前无法使用,可能是服务未启动
+VUE_APP_sAlgorithmAPIPROXY='http://192.168.50.235:8998/AnalysisMulti'
+VUE_APP_databaseApiAPIPROXY='http://192.168.50.234:3002'
+#暂时不知健康评估内网dev 环境地址
+VUE_APP_AnalysisMultiAPIPROXY='http://192.168.50.235:8998/AnalysisMulti'
+#暂时不知下载报告内网dev 环境地址
+VUE_APP_downLoadChartAPIPROXY=''

+ 1 - 1
.env.hd

@@ -7,7 +7,7 @@
  # @FilePath: /performance-test/.env.hd
 ### 
 # VUE_APP_MAPVIEW=http://192.168.0.1/tiles/{z}/{x}/{y}.png
-VUE_APP_MAPVIEW=http://192.168.50.235/tiles/{z}/{x}/{y}.png
+VUE_APP_MAPVIEW=/tiles/{z}/{x}/{y}.png
 VUE_APP_THEM="blue"
 VUE_APP_ISSHOWHD='HD'
 # VUE_APP_UPLOAD="http://192.168.0.1/energy-manage-service/api/check/upload"

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

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-13 13:56:55
- * @LastEditTime: 2025-07-24 10:49:46
+ * @LastEditTime: 2025-07-25 15:28:04
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/fault_all/index.vue
@@ -38,17 +38,17 @@
           :faultTypes="
             zongFaultCsvData &&
             zongFaultCsvData[0] &&
-            zongFaultCsvData[0].data.map((item) => item.fault_detail)
+            zongFaultCsvData[0].data.map((item) => item?.fault_detail)
           "
           :faultCounts="
             zongFaultCsvData &&
             zongFaultCsvData[0] &&
-            zongFaultCsvData[0].data.map((item) => item.count)
+            zongFaultCsvData[0].data.map((item) => item?.count)
           "
           :faultDurations="
             zongFaultCsvData &&
             zongFaultCsvData[0] &&
-            zongFaultCsvData[0].data.map((item) => item.fault_time_sum)
+            zongFaultCsvData[0].data.map((item) => item?.fault_time_sum)
           "
           :zongFaultCsvData="zongFaultCsvData"
         ></FaultAll>
@@ -57,7 +57,7 @@
           :key="'Time3DChart'"
           :index="`${new Date().getTime()}` + 'fen'"
           :ref="'Time3DChart'"
-          :fileAddr="item.fileAddr"
+          :fileAddr="item?.fileAddr"
         >
         </Time3DBarChart>
         <template v-for="(itemCsv, indCsv) in zongFaultCsvData">
@@ -80,7 +80,7 @@
               label="故障时长(小时)"
             >
               <template slot-scope="scope">
-                {{ Number(scope.row.fault_time_sum).toFixed(2) }}
+                {{ Number(scope.row?.fault_time_sum).toFixed(2) }}
               </template>
             </el-table-column>
             <el-table-column align="right">
@@ -163,6 +163,7 @@ export default {
     FilterChart,
     FaultAll,
     TinymceEditor,
+    Time3DBarChart,
   },
   props: {
     initBatchCode: {
@@ -212,22 +213,22 @@ export default {
       return (itemCsv) => {
         // 如果有搜索关键词,则过滤数据
         if (this.search) {
-          return itemCsv.data.filter((item) => {
-            return item.fault_detail
+          return itemCsv?.data?.filter((item) => {
+            return item?.fault_detail
               .toLowerCase()
               .includes(this.search.toLowerCase());
           });
         }
         // 没有搜索关键词时返回所有数据
-        return itemCsv.data;
+        return itemCsv?.data;
       };
     },
     filteredFenData() {
       return (itemCsv) => {
         // 如果有搜索关键词,则过滤数据
         if (this.searchFen) {
-          return itemCsv.data.filter((item) => {
-            return item.wind_turbine_name
+          return itemCsv?.data?.filter((item) => {
+            return item?.wind_turbine_name
               .toLowerCase()
               .includes(this.searchFen.toLowerCase());
           });
@@ -277,8 +278,8 @@ export default {
           analysisTypeCode: this.analysisTypeCode,
           commentList: this.editableTabs.map((item) => {
             return {
-              commentTypeCode: item.commentTypeCode,
-              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+              commentTypeCode: item?.commentTypeCode,
+              comment: item?.commentTypeName === "分析评论" ? this.comment : "",
             };
           }),
         });
@@ -319,8 +320,8 @@ export default {
                         .slice(0, result.data.length - 1)
                         .map((item) => ({
                           ...item,
-                          count: Number(item.count),
-                          fault_time_sum: Number(item.fault_time_sum) / 3600,
+                          count: Number(item?.count),
+                          fault_time_sum: Number(item?.fault_time_sum) / 3600,
                         })),
                     });
                   }
@@ -382,10 +383,10 @@ export default {
 
         if (result.data && result.data[0] && result.data[0].generalFiles) {
           result.data[0].generalFiles.map((item) => {
-            if (item.fileAddr) {
+            if (item?.fileAddr) {
               this.zongFaultCsvHeader = [];
               this.zongFaultCsvData = [];
-              this.fetchCsvData("fault", item.fileAddr);
+              this.fetchCsvData("fault", item?.fileAddr);
             }
           });
         } else {

+ 374 - 4
src/views/overview/components/min_pitch1/index.vue

@@ -1,13 +1,383 @@
 <!--
  * @Author: your name
  * @Date: 2025-07-24 17:07:30
- * @LastEditTime: 2025-07-24 17:10:19
+ * @LastEditTime: 2025-07-29 09:44:57
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/min_pitch1/index.vue
 -->
 <template>
-  <div>变桨频次</div>
+  <div class="type-variable">
+    <!-- 变桨频次 -->
+    <div class="left">
+      <FilterChart
+        :setUpimg="[]"
+        :isShowEngList="false"
+        :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 }"
+      >
+        <!-- {{ item.fileAddr }} -->
+        <BarChart
+          :setUpImgData="setUpImgData"
+          :key="item.batchCode + index"
+          :inds="`${new Date().getTime()}` + index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        ></BarChart>
+        <!-- <BarChart
+            :key="item.batchCode + index"
+            :inds="index + 'barChart'"
+            :ref="item.batchCode"
+            :fileAddr="item.fileAddr"
+          ></BarChart> -->
+      </VirtualList>
+      <el-dialog
+        v-if="isShowDescription"
+        title="添加评论"
+        :visible="isShow"
+        width="30%"
+        v-dialogDrag
+        :modal="false"
+        :lock-scroll="false"
+        :modal-append-to-body="false"
+        @close="handleClose"
+      >
+        <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"
+          style="margin: 20px 60px 0 0"
+        >
+          <el-col :span="2">
+            <el-button type="primary" size="small" @click="handleComment"
+              >提交评论</el-button
+            >
+          </el-col>
+        </el-row>
+      </el-dialog>
+    </div>
+    <div class="right" v-if="isShowTinymceEditorCom">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
-<script></script>
-<style></style>
+<script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import BarChart from "@/views/performance/components/chartsCom/BarChart.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import {
+  analysisDetail,
+  queryAnalysisedEngine,
+  analysisCommentEdit,
+} from "@/api/performance";
+
+export default {
+  name: "windSpee",
+  components: {
+    DicCard,
+    FilterChart,
+    BarChart,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    isShowTinymceEditorCom: {
+      default: true,
+      type: Boolean,
+    },
+    isShow: {
+      default: false,
+      type: Boolean,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      setUpImgData: [],
+      comment: "",
+      options: [],
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+      isShowDescription: false,
+    };
+  },
+  watch: {
+    isShow() {
+      if (this.isShow) {
+        if (!this.isShowDescription) {
+          this.$message({
+            message: "当前分析模型暂无分析,不能进行评论操作",
+            type: "warning",
+          });
+          this.$emit("setIsShow");
+        }
+      }
+    },
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    handleClose() {
+      //关闭评论弹框
+      this.$emit("setIsShow");
+    },
+    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();
+        this.$emit("setIsShow");
+      } 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.length > 0) {
+          this.isShowDescription = true;
+        }
+        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 &&
+            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, setUpImg) {
+      this.fieldEngineCodes = data;
+      this.setUpImgData = [...setUpImg];
+      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">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+  .left {
+    width: 30%;
+    height: 100%;
+    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: 0px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+.el-dialog__wrapper {
+  position: relative !important;
+}
+::v-deep .el-dialog {
+  position: fixed !important;
+  z-index: 999 !important;
+  top: 50%;
+  left: 50%;
+  transform: translate(0, -50%);
+}
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 381 - 4
src/views/overview/components/min_pitch2/index.vue

@@ -1,13 +1,390 @@
 <!--
  * @Author: your name
  * @Date: 2025-07-24 17:07:43
- * @LastEditTime: 2025-07-24 17:10:33
+ * @LastEditTime: 2025-07-29 14:28:17
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/min_pitch2/index.vue
 -->
+<!-- 
+1、演示环境新增页面数据联调
+-->
 <template>
-  <div>变桨角度差异</div>
+  <div class="type-variable">
+    <!-- 变桨角度差异 -->
+    <div class="left scroller">
+      <FilterChart
+        :setUpimg="[]"
+        :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>
+        <div style="font-size: 12px; margin-top: 10px">
+          <!-- 1.
+          温度是预示机械和电气故障的早期指标之一。通过监测关键部件如齿轮箱、发电机、轴承的温度,可以及时发现异常状况。这种早期检测允许采取预防性措施,从而避免成本高昂的维修和长时间的停机。 -->
+        </div>
+      </el-alert>
+      <div
+        class="titleCharts"
+        v-if="diagramRelationsDatas && diagramRelationsDatas.length > 0"
+      >
+        分析分图 :
+      </div>
+      <el-empty description="暂无分图分析记录" v-else></el-empty>
+      <VirtualList
+        :list="[...diagramRelationsDatas]"
+        keyField="fileAddr"
+        :itemSize="500"
+        v-slot="{ item, index }"
+      >
+        <lineScatter
+          :setUpImgData="setUpImgData"
+          :key="item.fieldEngineCode + index"
+          :index="`${new Date().getTime()}` + index"
+          :ref="item.fieldEngineCode"
+          :fieldEngineCode="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineScatter>
+      </VirtualList>
+      <el-dialog
+        v-if="isShowDescription"
+        title="添加评论"
+        :visible="isShow"
+        width="30%"
+        v-dialogDrag
+        :modal="false"
+        :lock-scroll="false"
+        :modal-append-to-body="false"
+        @close="handleClose"
+      >
+        <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"
+          style="margin: 20px 60px 0 0"
+        >
+          <el-col :span="2">
+            <el-button type="primary" size="small" @click="handleComment"
+              >提交评论</el-button
+            >
+          </el-col>
+        </el-row>
+      </el-dialog>
+    </div>
+    <div class="right" v-if="isShowTinymceEditorCom">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
-<script></script>
-<style></style>
+<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 lineScatter from "@/views/performance/components/chartsCom/lineScatter.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+
+import {
+  analysisDetail,
+  queryAnalysisedEngine,
+  analysisCommentEdit,
+} from "@/api/performance";
+
+export default {
+  name: "temperature_large_components_tem_deviation",
+  components: {
+    DicCard,
+    FilterChart,
+    lineAndChildLine,
+    lineScatter,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    isShowTinymceEditorCom: {
+      default: true,
+      type: Boolean,
+    },
+    isShow: {
+      default: false,
+      type: Boolean,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      setUpImgData: [],
+      comment: "",
+      options: [],
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      diagramRelationsDatas: [], //分图
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+      isShowDescription: false,
+    };
+  },
+  watch: {
+    isShow() {
+      if (this.isShow) {
+        if (!this.isShowDescription) {
+          this.$message({
+            message: "当前分析模型暂无分析,不能进行评论操作",
+            type: "warning",
+          });
+          this.$emit("setIsShow");
+        }
+      }
+    },
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    handleClose() {
+      //关闭评论弹框
+      this.$emit("setIsShow");
+    },
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: "temperature_large_components",
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+        this.$emit("setIsShow");
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        // 获取分析详情
+        await this.getAnalysisDetail();
+        // 获取风机列表
+        await this.getWindEnfineList(
+          this.initBatchCode,
+          "temperature_large_components"
+        );
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: "temperature_large_components",
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (result.data.length > 0) {
+          this.isShowDescription = true;
+        }
+        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.diagramRelationsDatas =
+          (result.data &&
+            result.data[0] &&
+            result.data[0].diagramRelations &&
+            result.data[0].diagramRelations
+              .filter((item) => item.fileAddr.endsWith(".json"))
+              .filter((item) =>
+                item.fileAddr.includes("GeneratorTemperature")
+              )) ||
+          [];
+      } 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, setUpImg) {
+      this.fieldEngineCodes = data;
+      this.setUpImgData = [...setUpImg];
+      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">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    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: 0px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+.el-dialog__wrapper {
+  position: relative !important;
+}
+::v-deep .el-dialog {
+  position: fixed !important;
+  z-index: 999 !important;
+  top: 50%;
+  left: 50%;
+  transform: translate(0, -50%);
+}
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 409 - 4
src/views/overview/components/min_pitch3/index.vue

@@ -1,13 +1,418 @@
 <!--
  * @Author: your name
  * @Date: 2025-07-24 17:07:55
- * @LastEditTime: 2025-07-24 17:10:50
+ * @LastEditTime: 2025-07-29 09:44:49
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/min_pitch3/index.vue
 -->
 <template>
-  <div>变桨电机温升</div>
+  <div class="type-variable">
+    <!-- 变桨电机温升 -->
+    <div class="left scroller">
+      <FilterChart
+        :setUpimg="[]"
+        :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>
+
+      <VirtualList
+        :list="[...generalFilesDatas, ...diagramRelationsDatas]"
+        keyField="fileAddr"
+        :itemSize="500"
+        v-slot="{ item, index }"
+      >
+        <div
+          class="titleCharts"
+          v-if="
+            generalFilesDatas &&
+            generalFilesDatas.length > 0 &&
+            item.engineTypeCode &&
+            generalFilesDatas[0].engineTypeCode === item.engineTypeCode
+          "
+        >
+          分析总图 :
+        </div>
+        <lineAndChildLine
+          v-if="item.batchCode && !item.fieldEngineCode"
+          :setUpImgData="setUpImgData"
+          :key="item.batchCode + index"
+          :index="`${new Date().getTime()}` + index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineAndChildLine>
+        <div
+          class="titleCharts"
+          v-if="
+            diagramRelationsDatas &&
+            diagramRelationsDatas.length > 0 &&
+            item.fieldEngineCode &&
+            diagramRelationsDatas[0].fieldEngineCode === item.fieldEngineCode
+          "
+        >
+          分析分图 :
+        </div>
+        <lineChartsFen
+          v-if="item.fieldEngineCode"
+          :setUpImgData="setUpImgData"
+          :key="item.fieldEngineCode + index"
+          :index="`${new Date().getTime()}` + index"
+          :ref="item.fieldEngineCode"
+          :fieldEngineCode="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineChartsFen>
+      </VirtualList>
+      <el-empty
+        description="暂无分析记录"
+        v-if="
+          generalFilesDatas.length === 0 && diagramRelationsDatas.length === 0
+        "
+      ></el-empty>
+      <el-dialog
+        v-if="isShowDescription"
+        title="添加评论"
+        :visible="isShow"
+        width="30%"
+        v-dialogDrag
+        :modal="false"
+        :lock-scroll="false"
+        :modal-append-to-body="false"
+        @close="handleClose"
+      >
+        <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"
+          style="margin: 20px 60px 0 0"
+        >
+          <el-col :span="2">
+            <el-button type="primary" size="small" @click="handleComment"
+              >提交评论</el-button
+            >
+          </el-col>
+        </el-row>
+      </el-dialog>
+    </div>
+    <div class="right" v-if="isShowTinymceEditorCom">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
-<script></script>
-<style></style>
+<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,
+  analysisCommentEdit,
+} from "@/api/performance";
+
+export default {
+  name: "tsrCpPower",
+  components: {
+    DicCard,
+    FilterChart,
+    lineAndChildLine,
+    lineChartsFen,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    isShowTinymceEditorCom: {
+      default: true,
+      type: Boolean,
+    },
+    isShow: {
+      default: false,
+      type: Boolean,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      setUpImgData: [],
+      comment: "",
+      options: [],
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+      isShowDescription: false,
+    };
+  },
+  watch: {
+    isShow() {
+      if (this.isShow) {
+        if (!this.isShowDescription) {
+          this.$message({
+            message: "当前分析模型暂无分析,不能进行评论操作",
+            type: "warning",
+          });
+          this.$emit("setIsShow");
+        }
+      }
+    },
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    handleClose() {
+      //关闭评论弹框
+      this.$emit("setIsShow");
+    },
+    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();
+        this.$emit("setIsShow");
+      } 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.length > 0) {
+          this.isShowDescription = true;
+        }
+        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 &&
+            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, setUpImg) {
+      this.fieldEngineCodes = data;
+      this.setUpImgData = [...setUpImg];
+      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">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    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: 0px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+.el-dialog__wrapper {
+  position: relative !important;
+}
+::v-deep .el-dialog {
+  position: fixed !important;
+  z-index: 999 !important;
+  top: 50%;
+  left: 50%;
+  transform: translate(0, -50%);
+}
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 1 - 1
src/views/overview/components/production_indicator1/index.vue

@@ -21,7 +21,7 @@
           </div>
         </template>
         <div style="font-size: 12px; margin-top: 10px">
-          风向玫瑰图是一种表示某地不同风向出现频率分布的图表。
+          <!-- 风向玫瑰图是一种表示某地不同风向出现频率分布的图表。 -->
         </div>
       </el-alert>
       <div class="titleCharts">分析分图 :</div>

+ 2 - 2
src/views/overview/components/production_indicator2/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-07-23 10:53:25
- * @LastEditTime: 2025-07-24 10:01:15
+ * @LastEditTime: 2025-07-29 09:46:07
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/production_indicator2/index.vue
@@ -30,7 +30,7 @@
           </div>
         </template>
         <div style="font-size: 12px; margin-top: 10px">
-          对各个机组整体状态评估的发电量和故障时长进行统计
+          <!-- 对各个机组整体状态评估的发电量和故障时长进行统计 -->
         </div>
       </el-alert>
       <div class="chartsBox" v-if="fenFaultCsvData.length > 0">

+ 6 - 4
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-04-11 16:51:42
+ * @LastEditTime: 2025-07-25 17:11:26
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/rated_power_windspeed/index.vue
@@ -36,15 +36,15 @@
       <div class="titleCharts">分析总图 :</div>
       <VirtualList
         :list="generalFilesDatas"
-        keyField="batchCode"
+        keyField="fileAddr"
         :itemSize="452"
         v-slot="{ item, index }"
       >
         <BoxLineCharts
           :setUpImgData="setUpImgData"
           :key="item.batchCode + index"
-          :index="`${new Date().getTime()}` + index"
-          :ref="`${new Date().getTime()}` + item.batchCode + index"
+          :index="item.batchCode + index"
+          :ref="item.batchCode + index"
           :fileAddr="item.fileAddr"
         >
         </BoxLineCharts>
@@ -262,6 +262,7 @@ export default {
               item.fileAddr.endsWith(".json")
             )) ||
           []; //总图数据
+
         this.diagramRelationsDatas =
           (result.data &&
             result.data[0] &&
@@ -270,6 +271,7 @@ export default {
               item.fileAddr.endsWith(".json")
             )) ||
           [];
+        console.log(this.generalFilesDatas, "this.generalFilesDatas");
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }

+ 2 - 1
src/views/overview/components/temperature_large_components_adriven/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-21 10:01:52
- * @LastEditTime: 2025-06-06 16:41:12
+ * @LastEditTime: 2025-07-28 14:19:09
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/temperature_large_components_adriven/index.vue
@@ -307,6 +307,7 @@ export default {
         ) {
           this.commentDescriptionVos = result.data[0].commentDescriptionVos;
         }
+        console.log(result.data, "result.data[0]");
         this.generalFilesDatas =
           (result.data &&
             result.data[0] &&

+ 392 - 4
src/views/overview/components/yaw_error1/index.vue

@@ -1,13 +1,401 @@
 <!--
  * @Author: your name
  * @Date: 2025-07-24 17:11:36
- * @LastEditTime: 2025-07-24 17:14:10
+ * @LastEditTime: 2025-07-29 16:46:29
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/yaw_error1/index.vue
 -->
+<!-- 偏航频次及速率 -->
 <template>
-  <div>偏航频次及速率</div>
+  <div class="type-variable">
+    <!-- 偏航异常检测 -->
+    <div class="left scroller">
+      <FilterChart
+        :setUpimg="[]"
+        :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>
+      <VirtualList
+        :list="[...generalFilesDatas, ...diagramRelationsDatas]"
+        keyField="fileAddr"
+        :itemSize="500"
+        v-slot="{ item, index }"
+      >
+        <div
+          class="titleCharts"
+          v-if="
+            generalFilesDatas &&
+            generalFilesDatas.length > 0 &&
+            item.engineTypeCode &&
+            generalFilesDatas[0].engineTypeCode === item.engineTypeCode
+          "
+        >
+          分析总图 :
+        </div>
+        <BarChart
+          v-if="item.batchCode && !item.fieldEngineCode"
+          :setUpImgData="setUpImgData"
+          :key="item.batchCode + index"
+          :inds="`${new Date().getTime()}` + index"
+          :ref="item.batchCode"
+          :fileAddr="item.fileAddr"
+        >
+        </BarChart>
+      </VirtualList>
+      <el-empty
+        description="暂无分析记录"
+        v-if="
+          generalFilesDatas.length === 0 && diagramRelationsDatas.length === 0
+        "
+      ></el-empty>
+      <el-dialog
+        v-if="isShowDescription"
+        title="添加评论"
+        :visible="isShow"
+        width="30%"
+        v-dialogDrag
+        :modal="false"
+        :lock-scroll="false"
+        :modal-append-to-body="false"
+        @close="handleClose"
+      >
+        <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"
+          style="margin: 20px 60px 0 0"
+        >
+          <el-col :span="2">
+            <el-button type="primary" size="small" @click="handleComment"
+              >提交评论</el-button
+            >
+          </el-col>
+        </el-row>
+      </el-dialog>
+    </div>
+    <div class="right" v-if="isShowTinymceEditorCom">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
-<script></script>
-<style></style>
+<script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import BarChart from "@/views/performance/components/chartsCom/BarChart.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import {
+  analysisDetail,
+  queryAnalysisedEngine,
+  analysisCommentEdit,
+} from "@/api/performance";
+
+export default {
+  name: "temperature_large_components_Winding_tem",
+  components: {
+    DicCard,
+    FilterChart,
+    BarChart,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    isShowTinymceEditorCom: {
+      default: true,
+      type: Boolean,
+    },
+    isShow: {
+      default: false,
+      type: Boolean,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      setUpImgData: [],
+      comment: "",
+      options: [],
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+      isShowDescription: false,
+    };
+  },
+  watch: {
+    isShow() {
+      if (this.isShow) {
+        if (!this.isShowDescription) {
+          this.$message({
+            message: "当前分析模型暂无分析,不能进行评论操作",
+            type: "warning",
+          });
+          this.$emit("setIsShow");
+        }
+      }
+    },
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    handleClose() {
+      //关闭评论弹框
+      this.$emit("setIsShow");
+    },
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: "temperature_large_components",
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+        this.$emit("setIsShow");
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        // 获取分析详情
+        await this.getAnalysisDetail();
+        // 获取风机列表
+        await this.getWindEnfineList(
+          this.initBatchCode,
+          "temperature_large_components"
+        );
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: "temperature_large_components",
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (result.data.length > 0) {
+          this.isShowDescription = true;
+        }
+        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"))
+              .filter((item) =>
+                item.fileAddr.includes("generator_winding1_temperature")
+              )) ||
+          []; //总图数据
+        this.diagramRelationsDatas =
+          (result.data &&
+            result.data[0] &&
+            result.data[0].diagramRelations &&
+            result.data[0].diagramRelations
+              .filter((item) => item.fileAddr.endsWith(".json"))
+              .filter((item) =>
+                item.fileAddr.includes("generator_winding1_temperature")
+              )) ||
+          [];
+      } 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, setUpImg) {
+      this.fieldEngineCodes = data;
+      this.setUpImgData = [...setUpImg];
+      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">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    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: 0px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+.el-dialog__wrapper {
+  position: relative !important;
+}
+::v-deep .el-dialog {
+  position: fixed !important;
+  z-index: 999 !important;
+  top: 50%;
+  left: 50%;
+  transform: translate(0, -50%);
+}
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 377 - 4
src/views/overview/components/yaw_error2/index.vue

@@ -1,13 +1,386 @@
 <!--
  * @Author: your name
  * @Date: 2025-07-24 17:12:39
- * @LastEditTime: 2025-07-24 17:14:17
+ * @LastEditTime: 2025-07-29 14:21:31
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/yaw_error2/index.vue
 -->
 <template>
-  <div>偏航时间占比</div>
+  <div class="type-variable">
+    <!-- 偏航时间占比 -->
+    <div class="left scroller">
+      <FilterChart
+        :setUpimg="[]"
+        :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>
+        <div style="font-size: 12px; margin-top: 10px">
+          <!-- 1.
+          温度是预示机械和电气故障的早期指标之一。通过监测关键部件如齿轮箱、发电机、轴承的温度,可以及时发现异常状况。这种早期检测允许采取预防性措施,从而避免成本高昂的维修和长时间的停机。 -->
+        </div>
+      </el-alert>
+      <div
+        class="titleCharts"
+        v-if="diagramRelationsDatas && diagramRelationsDatas.length > 0"
+      >
+        分析分图 :
+      </div>
+      <el-empty description="暂无分图分析记录" v-else></el-empty>
+      <VirtualList
+        :list="[...diagramRelationsDatas]"
+        keyField="fileAddr"
+        :itemSize="500"
+        v-slot="{ item, index }"
+      >
+        <lineScatter
+          :setUpImgData="setUpImgData"
+          :key="item.fieldEngineCode + index"
+          :index="`${new Date().getTime()}` + index"
+          :ref="item.fieldEngineCode"
+          :fieldEngineCode="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        >
+        </lineScatter>
+      </VirtualList>
+      <el-dialog
+        v-if="isShowDescription"
+        title="添加评论"
+        :visible="isShow"
+        width="30%"
+        v-dialogDrag
+        :modal="false"
+        :lock-scroll="false"
+        :modal-append-to-body="false"
+        @close="handleClose"
+      >
+        <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"
+          style="margin: 20px 60px 0 0"
+        >
+          <el-col :span="2">
+            <el-button type="primary" size="small" @click="handleComment">
+              提交评论
+            </el-button>
+          </el-col>
+        </el-row>
+      </el-dialog>
+    </div>
+    <div class="right" v-if="isShowTinymceEditorCom">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
-<script></script>
-<style></style>
+<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 lineScatter from "@/views/performance/components/chartsCom/lineScatter.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import {
+  analysisDetail,
+  queryAnalysisedEngine,
+  analysisCommentEdit,
+} from "@/api/performance";
+
+export default {
+  name: "temperature_large_components_tem_deviation",
+  components: {
+    DicCard,
+    FilterChart,
+    lineAndChildLine,
+    lineScatter,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    isShowTinymceEditorCom: {
+      default: true,
+      type: Boolean,
+    },
+    isShow: {
+      default: false,
+      type: Boolean,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      setUpImgData: [],
+      comment: "",
+      options: [],
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      diagramRelationsDatas: [], //分图
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+      isShowDescription: false,
+    };
+  },
+  watch: {
+    isShow() {
+      if (this.isShow) {
+        if (!this.isShowDescription) {
+          this.$message({
+            message: "当前分析模型暂无分析,不能进行评论操作",
+            type: "warning",
+          });
+          this.$emit("setIsShow");
+        }
+      }
+    },
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    handleClose() {
+      //关闭评论弹框
+      this.$emit("setIsShow");
+    },
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: "temperature_large_components",
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+        this.$emit("setIsShow");
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        // 获取分析详情
+        await this.getAnalysisDetail();
+        // 获取风机列表
+        await this.getWindEnfineList(
+          this.initBatchCode,
+          "temperature_large_components"
+        );
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: "temperature_large_components",
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (result.data.length > 0) {
+          this.isShowDescription = true;
+        }
+        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.diagramRelationsDatas =
+          (result.data &&
+            result.data[0] &&
+            result.data[0].diagramRelations &&
+            result.data[0].diagramRelations
+              .filter((item) => item.fileAddr.endsWith(".json"))
+              .filter((item) =>
+                item.fileAddr.includes("GeneratorTemperature")
+              )) ||
+          [];
+      } 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, setUpImg) {
+      this.fieldEngineCodes = data;
+      this.setUpImgData = [...setUpImg];
+      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">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    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: 0px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+.el-dialog__wrapper {
+  position: relative !important;
+}
+::v-deep .el-dialog {
+  position: fixed !important;
+  z-index: 999 !important;
+  top: 50%;
+  left: 50%;
+  transform: translate(0, -50%);
+}
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 1 - 1
src/views/overview/components/yaw_error3/index.vue

@@ -28,7 +28,7 @@
           </div>
         </template>
         <div style="font-size: 12px; margin-top: 10px">
-          大部件温度分析在风电机组的运维和性能管理中扮演着极为关键的角色。以下是温度分析的几个重要作用:
+          <!-- 大部件温度分析在风电机组的运维和性能管理中扮演着极为关键的角色。以下是温度分析的几个重要作用: -->
         </div>
       </el-alert>
       <VirtualList

+ 371 - 4
src/views/overview/components/yaw_error4/index.vue

@@ -1,13 +1,380 @@
 <!--
  * @Author: your name
  * @Date: 2025-07-24 17:13:23
- * @LastEditTime: 2025-07-24 17:14:33
+ * @LastEditTime: 2025-07-29 09:45:41
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/yaw_error4/index.vue
 -->
 <template>
-  <div>偏航余压</div>
+  <div class="type-variable">
+    <!-- 偏航余压--只有分图不存在总图 -->
+    <div class="left">
+      <FilterChart
+        :setUpimg="[]"
+        :isShowEngList="false"
+        :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="fileAddr"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <BoxLineCharts
+          :setUpImgData="setUpImgData"
+          :key="item.batchCode + index"
+          :index="item.batchCode + index"
+          :ref="item.batchCode + index"
+          :fileAddr="item.fileAddr"
+        >
+        </BoxLineCharts>
+      </VirtualList>
+      <el-dialog
+        v-if="isShowDescription"
+        title="添加评论"
+        :visible="isShow"
+        width="30%"
+        v-dialogDrag
+        :modal="false"
+        :lock-scroll="false"
+        :modal-append-to-body="false"
+        @close="handleClose"
+      >
+        <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"
+          style="margin: 20px 60px 0 0"
+        >
+          <el-col :span="2">
+            <el-button type="primary" size="small" @click="handleComment"
+              >提交评论</el-button
+            >
+          </el-col>
+        </el-row>
+      </el-dialog>
+    </div>
+    <div class="right" v-if="isShowTinymceEditorCom">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
-<script></script>
-<style></style>
+<script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import BoxLineCharts from "@/views/performance/components/chartsCom/BoxLineCharts.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import {
+  analysisDetail,
+  queryAnalysisedEngine,
+  analysisCommentEdit,
+} from "@/api/performance";
+
+export default {
+  name: "ratedPowerWindspeed",
+  components: {
+    DicCard,
+    FilterChart,
+    BoxLineCharts,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    isShowTinymceEditorCom: {
+      default: true,
+      type: Boolean,
+    },
+    isShow: {
+      default: false,
+      type: Boolean,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      setUpImgData: [],
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图,
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+      isShowDescription: false,
+    };
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    isShow() {
+      if (this.isShow) {
+        if (!this.isShowDescription) {
+          this.$message({
+            message: "当前分析模型暂无分析,不能进行评论操作",
+            type: "warning",
+          });
+          this.$emit("setIsShow");
+        }
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    handleClose() {
+      //关闭评论弹框
+      this.$emit("setIsShow");
+    },
+    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();
+        this.$emit("setIsShow");
+      } 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.length > 0) {
+          this.isShowDescription = true;
+        }
+        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 &&
+            result.data[0].diagramRelations.filter((item) =>
+              item.fileAddr.endsWith(".json")
+            )) ||
+          [];
+        console.log(this.generalFilesDatas, "this.generalFilesDatas");
+      } 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, setUpImg) {
+      this.fieldEngineCodes = data;
+      this.setUpImgData = [...setUpImg];
+      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">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    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: 0px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+.el-dialog__wrapper {
+  position: relative !important;
+}
+::v-deep .el-dialog {
+  position: fixed !important;
+  z-index: 999 !important;
+  top: 50%;
+  left: 50%;
+  transform: translate(0, -50%);
+}
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

+ 139 - 214
src/views/performance/components/chartsCom/BarChart.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2024-09-11 14:30:17
- * @LastEditTime: 2025-07-10 10:38:19
+ * @LastEditTime: 2025-07-25 16:06:58
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/BarChart.vue
@@ -11,7 +11,10 @@
   <div>
     <!-- 图表控制面板 -->
     <div style="display: flex; align-items: center">
-      <div style="margin-right: 20px; display: flex; align-items: center">
+      <div
+        v-if="chartData.data.length < 2"
+        style="margin-right: 20px; display: flex; align-items: center"
+      >
         <el-color-picker
           size="small"
           v-model="color1"
@@ -20,6 +23,31 @@
         ></el-color-picker>
         <span style="margin-left: 10px">自定义颜色</span>
       </div>
+      <el-select
+        v-else
+        size="small"
+        v-model="color1"
+        @change="updateChartColor"
+        placeholder="选择配色方案"
+        style="width: 200px"
+      >
+        <el-option
+          v-for="(scheme, index) in colorSchemes"
+          :key="index"
+          :label="scheme.label"
+          :value="scheme.colors"
+        >
+          <span
+            v-for="color in scheme.colors.slice(0, 8)"
+            :style="{
+              background: color,
+              width: '20px',
+              height: '20px',
+              display: 'inline-block',
+            }"
+          ></span>
+        </el-option>
+      </el-select>
       <div>
         <el-button size="small" @click="toggleChartType">
           切换为{{ chartType === "bar" ? "折线图" : "柱状图" }}
@@ -31,6 +59,7 @@
     <div
       v-loading="loading"
       :id="`bar-chart-${inds}`"
+      :ref="`bar-chart${inds}`"
       style="width: 100%; height: 400px"
     >
       <el-empty v-if="isError" description="请求失败"></el-empty>
@@ -42,8 +71,9 @@
 import { nextTick } from "vue"; // 导入 nextTick
 import Plotly from "plotly.js-dist";
 import axios from "axios";
+import { colorSchemes } from "@/views/overview/js/colors";
 import { myMixin } from "@/mixins/chartRequestMixin";
-
+import { mapState } from "vuex";
 export default {
   props: {
     fileAddr: {
@@ -68,14 +98,46 @@ export default {
         yaixs: "",
         data: [],
       },
+      color1: null, // 默认颜色
       chartType: "bar", // 当前图表类型 ('bar' 或 'scatter')
-      color1: "#588CF0", // 默认颜色
+      // color1: "#588CF0", // 默认颜色
+      // 配色方案列表(每个方案是一个颜色数组)
+      colorSchemes: colorSchemes,
+      colors: [...colorSchemes[0].colors],
       // normalRangeMin: 5, // 最低范围
       // normalRangeMax: 18, // 最高范围
     };
   },
+  watch: {
+    themeColor: {
+      handler(newVal, oldVal) {
+        if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
+          this.color1 = newVal;
+          this.updateChartColor();
+        }
+      },
+      deep: true,
+    },
+    setUpImgData: {
+      handler(newVal, oldVal) {
+        if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
+          this.drawChart();
+        }
+      },
+      deep: true,
+    },
+  },
   mounted() {
-    this.getData();
+    if (this.fileAddr) {
+      this.$nextTick(() => {
+        this.getData();
+      });
+    }
+  },
+  computed: {
+    ...mapState("themes", {
+      themeColor: "themeColor",
+    }),
   },
   methods: {
     async getData() {
@@ -88,12 +150,16 @@ export default {
             cancelToken: this.cancelToken.token,
           });
           this.chartData = resultChartsData.data;
+          this.color1 =
+            this.chartData.data.length >= 2
+              ? colorSchemes[0].colors
+              : "#588CF0";
           // 使用 nextTick 来确保 DOM 渲染完成后绘制图表
           nextTick(() => {
             this.drawChart();
-            this.isError = false;
-            this.loading = false;
           });
+          this.isError = false;
+          this.loading = false;
         } catch (error) {
           if (axios.isCancel(error)) {
             console.warn("请求被取消:", error.message);
@@ -106,231 +172,73 @@ export default {
     },
     // 绘制图表
     drawChart() {
-      if (this.chartData.data && this.chartData.data.length === 0) return;
-      const chartDataset = this.chartData.data[0];
-      const trace = {
-        x: chartDataset.xData, // 横坐标数据
-        y: chartDataset.yData, // 纵坐标数据
-        type: this.chartType, // 当前图表类型 ('bar' 或 'scatter')
-        marker: {
-          color: this.color1, // 柱状图颜色
-        },
-        line: {
-          color: this.color1, // 折线图颜色
-        },
-        name: chartDataset.title || "数据", // 图例名称
-        hovertemplate:
-          `${this.chartData.xaixs}:` +
-          ` %{x} <br> ` +
-          `${this.chartData.yaixs}:` +
-          "%{y} <br>",
-      };
+      if (!this.chartData.data || this.chartData.data.length === 0) return;
+
+      const data = this.chartData.data.map((chartDataset, index) => {
+        return {
+          x: chartDataset.xData,
+          y: chartDataset.yData,
+          type: this.chartType, // 'bar' | 'scatter' | 'line'
+          name: chartDataset.title || `系列 ${index + 1}`,
+          marker: {
+            color:
+              this.chartData.data.length >= 2
+                ? colorSchemes[0].colors[colorSchemes[0].colors.length - index]
+                : "#588CF0", // 多颜色支持
+          },
+          line: {
+            color:
+              this.chartData.data.length >= 2
+                ? colorSchemes[0].colors[colorSchemes[0].colors.length - index]
+                : "#588CF0", // 多颜色支持
+          },
+          hovertemplate:
+            `${this.chartData.xaixs}: %{x}<br>` +
+            `${this.chartData.yaixs}: %{y}<br>`,
+        };
+      });
 
       const layout = {
         title: {
-          text: chartDataset.title,
+          text: this.chartData.title || this.chartData.data[0].title,
           font: {
-            size: 16, // 设置标题字体大小(默认 16)
+            size: 16,
             weight: "bold",
           },
-        }, // 图表标题
+        },
         xaxis: {
-          title: this.chartData.xaixs || "X轴", // 横坐标标题
+          title: this.chartData.xaixs || "X轴",
           gridcolor: "rgb(255,255,255)",
-          type: this.chartData.xaixs === "机组" ? "category" : undefined, // 让 Y 轴按类别均匀分布
+          type:
+            this.chartData.xaixs === "机组" ||
+            this.chartData.xaixs === "机组名称"
+              ? "category"
+              : undefined,
           tickcolor: "rgb(255,255,255)",
-          backgroundcolor: "#e5ecf6",
           dtick: this.chartData.xaixs === "风速(m/s)" ? 1 : undefined,
         },
         yaxis: {
-          title: this.chartData.yaixs || "Y轴", // 纵坐标标题
+          title: this.chartData.yaixs || "Y轴",
           gridcolor: "rgb(255,255,255)",
           tickcolor: "rgb(255,255,255)",
-          backgroundcolor: "#e5ecf6",
-          title_standoff: 100, // 设置标题与轴的距离
-        },
-        margin: {
-          l: 50,
-          r: 50,
-          t: 50,
-          b: 50,
         },
         plot_bgcolor: "#e5ecf6",
-        gridcolor: "#fff",
-        bgcolor: "#e5ecf6", // 设置背景颜色
-        autosize: true, // 开启自适应
+        paper_bgcolor: "#e5ecf6",
+        barmode: "stack", // ✅ 堆叠模式
+        margin: { l: 50, r: 50, t: 50, b: 50 },
       };
-      // **如果 Y 轴是 "温度偏差",添加两条红色虚线**
-      if (this.chartData.data[0].title === "温度偏差") {
-        layout.shapes = [
-          {
-            type: "line",
-            xref: "paper", // x 轴相对于整个图
-            yref: "y",
-            x0: 0,
-            x1: 1, // 从左到右整个图表
-            y0: 5,
-            y1: 5,
-            line: {
-              color: "red",
-              width: 2,
-              dash: "dash", // 虚线
-            },
-            // ✅ 添加 hoverlabel
-            hovertext: "上限: 5°C",
-            hoverinfo: "text",
-          },
-          {
-            type: "line",
-            xref: "paper",
-            yref: "y",
-            x0: 0,
-            x1: 1,
-            y0: -5,
-            y1: -5,
-            line: {
-              color: "red",
-              width: 2,
-              dash: "dash", // 虚线
-            },
-
-            hovertext: "下限: -5°C",
-            hoverinfo: "text",
-          },
-        ];
-        layout.hovermode = "x unified";
-      }
-      if (
-        this.chartData.xaixs === "机组" ||
-        this.chartData.xaixs === "机组名称"
-      ) {
-        layout.xaxis.tickvals = this.chartData.data[0].xData;
-        layout.xaxis.ticktext = this.chartData.data[0].xData;
-      }
-
-      // 渲染图表
-      Plotly.newPlot(
-        `bar-chart-${this.inds}`,
-
-        // [trace, normalRangeLine, normalRangeMaxLine],
-        [trace],
-        { ...layout },
-        {
-          displaylogo: false,
-          responsive: true,
-          modeBarButtonsToRemove: [
-            // "pan2d", // 平移按钮
-            "zoom2d", // 缩放按钮
-            // "select2d", // 选择框
-            // "lasso2d", // 套索选择
-            // "resetScale2d", // 重置轴
-            // // "zoomIn", // 放大
-            // // "zoomOut", // 缩小
-            // "home", // 重置
-            // "toImage", // 导出为图片
-            // "hoverClosestCartesian", // 悬浮信息
-            // "zoomIn2d", // 缩放按钮(详细版本)
-            // "zoomOut2d", // 缩放按钮(详细版本)
-            // "autoScale2D",
-            // "plotlylogo2D",
-            // "Produced with Plotly.js(v2.35)", // 删除 Plotly logo
-          ],
 
-          // modeBarButtonsToAdd: [
-          //   {
-          //     name: "保存图片", // 直接写中文翻译
-          //     icon: Plotly.Icons["camera"],
-          //     click: function () {
-          //       console.log("选择框");
-          //       Plotly.downloadImage(gd, {
-          //         format: "png",
-          //         width: 800,
-          //         height: 600,
-          //       });
-          //     },
-          //   },
-          //   {
-          //     name: "选择框", // 直接写中文翻译
-          //     icon: Plotly.Icons["selectbox"],
-          //     click: function () {
-          //       console.log("选择框");
-          //     },
-          //   },
-          //   {
-          //     name: "套索选择", // 直接写中文翻译
-          //     icon: Plotly.Icons.lasso,
-          //     click: function () {
-          //       console.log("套索选择");
-          //     },
-          //   },
-          //   {
-          //     name: "放大", // 直接写中文翻译
-          //     icon: Plotly.Icons["zoom_plus"],
-          //     click: function () {
-          //       console.log("放大", Plotly.Icons);
-          //     },
-          //   },
-          //   {
-          //     name: "缩小", // 直接写中文翻译
-          //     icon: Plotly.Icons["zoom_minus"],
-          //     click: function () {
-          //       console.log("缩小", Plotly.Icons);
-          //     },
-          //   },
-          //   {
-          //     name: "缩放", // 直接写中文翻译
-          //     icon: Plotly.Icons["zoombox"],
-          //     click: function () {
-          //       console.log("缩放", Plotly.Icons);
-          //     },
-          //   },
-          //   {
-          //     name: "平移", // 直接写中文翻译
-          //     icon: Plotly.Icons.pan,
-          //     click: function () {
-          //       console.log("平移");
-          //     },
-          //   },
-          //   {
-          //     name: "还原", // 直接写中文翻译
-          //     icon: Plotly.Icons.home,
-          //     click: function () {
-          //       // 获取图表的 DOM 元素
-          //       var gd = document.getElementById(`bar-chart${this.inds}`);
-          //       Plotly.relayout(gd, {
-          //         "xaxis.range": null,
-          //         "yaxis.range": null,
-          //       });
-          //     },
-          //   },
-          // ], // 这个必须是数组类型
-        }
-      ).then(function (gd) {
-        // 获取工具栏按钮
-        const toolbar = gd.querySelector(".modebar");
-        const buttons = toolbar.querySelectorAll(".modebar-btn");
-
-        // 定义一个映射对象,方便修改按钮提示
-        const titleMap = {
-          "Download plot as a png": "保存图片",
-          Autoscale: "缩放",
-          Pan: "平移",
-          "Zoom out": "缩小",
-          "Zoom in": "放大",
-          "Box Select": "选择框操作",
-          "Lasso Select": "套索选择操作",
-          "Reset axes": "重置操作",
-        };
-
-        // 遍历所有按钮,修改它们的 title
-        buttons.forEach(function (button) {
-          const dataTitle = button.getAttribute("data-title");
-
-          // 如果标题匹配,修改属性值
-          if (titleMap[dataTitle]) {
-            button.setAttribute("data-title", titleMap[dataTitle]);
-          }
-        });
+      Plotly.newPlot(`bar-chart-${this.inds}`, data, layout, {
+        responsive: true,
+        displaylogo: false,
+        modeBarButtonsToRemove: [
+          "zoom2d",
+          "zoomIn2d",
+          "zoomOut2d",
+          "autoScale2d",
+          "lasso2d",
+          "sendDataToCloud",
+        ],
       });
     },
     // 切换图表类型
@@ -342,6 +250,23 @@ export default {
     updateChartColor() {
       this.drawChart();
     },
+    // 根据配色方案设置每个选项的样式
+    getOptionStyle(scheme) {
+      return {
+        background: `linear-gradient(to right, ${scheme
+          .slice(0, 8)
+          .join(", ")})`,
+        color: "#fff",
+        height: "30px",
+        lineHeight: "30px",
+        borderRadius: "0px",
+      };
+    },
+  },
+  beforeUnmount() {
+    if (this.cancelToken) {
+      this.cancelToken.cancel("组件卸载,取消请求");
+    }
   },
 };
 </script>

+ 1 - 0
src/views/performance/components/chartsCom/BoxLineCharts.vue

@@ -245,6 +245,7 @@ export default {
       }
 
       this.$nextTick(() => {
+        //plotDivBox-${index}
         const plotDiv = document.getElementById(`plotDivBox-${this.index}`);
         if (plotDiv) {
           Plotly.newPlot(plotDiv, [trace, trace2], layout, {

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

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-07-24 17:30:10
- * @LastEditTime: 2025-07-25 09:20:20
+ * @LastEditTime: 2025-07-29 14:41:53
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/LineAndScatter.vue
@@ -57,7 +57,7 @@
 import { nextTick } from "vue"; // 导入 nextTick
 import Plotly from "plotly.js-dist";
 import axios from "axios";
-import { colorSchemes } from "@/views/overview/js/colors";
+import { colorSchemes } from "@/views/overview/js/colors.js";
 import { myMixin } from "@/mixins/chartRequestMixin"; // 假设你需要的 mixin
 import { mapState } from "vuex";
 export default {
@@ -168,6 +168,7 @@ export default {
           y: turbine.yData, // Y 数据
           name: turbine.engineName, // 使用机组名称
           type: "scattergl", // 使用散点图
+          mode: index === 0 ? "lines" : "markers",
           //   line: {
           //     color:
           //       this.color1.length > 0
@@ -175,12 +176,9 @@ export default {
           //         : this.colors[index % this.colors.length], // 为每个机组分配不同的颜色
           //   },
           marker: {
-            color:
-              this.color1.length > 0
-                ? this.color1[index % this.color1.length]
-                : this.colors[index % this.colors.length], // 为每个机组分配不同的颜色
-            size: 12,
-            symbol: "x", // 也可以是 "circle", "diamond", "x", etc.
+            color: index === 0 ? "#3856A0" : index === 1 ? "#77BDC2" : "red", // 为每个机组分配不同的颜色
+            // size: 12,
+            symbol: index === 0 ? "circle" : index === 1 ? "x" : "etc.", // 也可以是 "circle", "diamond", "x", etc.
           },
           hovertemplate:
             `${this.chartData.xaixs}:` +
@@ -213,6 +211,7 @@ export default {
           gridcolor: "rgb(255,255,255)",
           tickcolor: "rgb(255,255,255)",
           backgroundcolor: "#e5ecf6",
+          backgroundcolor: "#e5ecf6",
           dtick: this.chartData.xaixs === "风速" ? 1 : undefined,
           range:
             this.chartData.analysisTypeCode === "风电机组风能利用系数分析" &&
@@ -237,6 +236,16 @@ export default {
               ? [0, 1.5]
               : undefined,
         },
+        yaxis2: {
+          title: "yaw state",
+          titlefont: { color: "#1A295D" },
+          tickfont: { color: "#1A295D" },
+          overlaying: "y", // 在第一个 Y 轴上方绘制
+          side: "right", // 右侧的 Y 轴
+          position: 1, // 调整右侧轴的位置
+          showline: true,
+          linecolor: "#1A295D", // 设置右侧轴线颜色
+        },
         margin: {
           l: 50,
           r: 50,

+ 134 - 0
src/views/performance/components/chartsCom/json/#34_min_pitch2.json

@@ -0,0 +1,134 @@
+{
+    "analysisTypeCode": "变桨角度差异分析",
+    "engineCode": "WEM00041",
+    "engineTypeName": "",
+    "xaixs": "日期",
+    "yaixs": "变桨角度差异",
+    "data": [
+        {
+            "title": " #34变桨角度差异分布",
+            "engineName": "#34",
+            "engineCode": "WOG01312",
+            "xData": [
+                "1-1",
+                "1-2",
+                "1-3",
+                "1-4",
+                "1-5",
+                "1-6",
+                "1-7",
+                "1-8",
+                "1-9",
+                "1-10",
+                "1-11",
+                "1-12",
+                "1-13",
+                "1-14",
+                "1-15",
+                "1-16",
+                "1-17",
+                "1-18",
+                "1-19",
+                "1-20",
+                "1-21",
+                "1-31",
+                "2-1",
+                "2-3",
+                "2-4",
+                "11-12",
+                "11-13",
+                "11-14",
+                "11-15",
+                "11-16",
+                "11-17",
+                "11-18",
+                "11-19",
+                "12-2",
+                "12-3",
+                "12-4",
+                "12-5",
+                "12-6",
+                "12-7",
+                "12-8",
+                "12-9",
+                "12-10",
+                "12-11",
+                "12-12",
+                "12-13",
+                "12-14",
+                "12-15",
+                "12-16",
+                "12-17",
+                "12-18",
+                "12-19",
+                "12-20",
+                "12-21",
+                "12-22",
+                "12-23",
+                "12-24",
+                "12-25",
+                "12-26"
+            ],
+            "yData": [
+                0.0,
+                0.0,
+                0.0008333333581686036,
+                0.0008999982834059702,
+                0.0007000000059604656,
+                0.0006333384831880195,
+                0.00043333409629065693,
+                0.0008333333581686036,
+                0.0011999977111826965,
+                0.0008333396911741176,
+                0.0005333339055380738,
+                9.999999552965206e-05,
+                0.0005333354949973905,
+                0.0008333357175207112,
+                0.0008333333581686036,
+                0.00103333334922792,
+                0.0005333323160812854,
+                0.00043333409629047934,
+                0.000633333516121346,
+                0.000533335494997124,
+                0.0002999994277956919,
+                0.0008333357175207038,
+                0.000533333309491475,
+                0.0008333317438770897,
+                0.0008333357175210443,
+                0.00013333307902038644,
+                0.00013333332737286674,
+                0.00013333943691878382,
+                0.00013333307902025618,
+                0.00013333943691878382,
+                0.0001333394369191865,
+                9.99999582767729e-05,
+                0.00010000457768908789,
+                0.00010000457768938987,
+                0.0001333338737493343,
+                2.270699402618506,
+                0.002133333237965905,
+                9.999999552965007e-05,
+                0.00013332672127331098,
+                3.3334859230140064e-05,
+                0.00013333943691878385,
+                0.0001333394369191865,
+                0.0027000002145767263,
+                0.004799999785423282,
+                0.0008333333581686036,
+                9.999999552965007e-05,
+                3.333485923012822e-05,
+                0.000433333276708925,
+                0.00010000010728838882,
+                0.0001333333273728694,
+                3.333485922973149e-05,
+                0.0,
+                0.0005333323160812854,
+                0.0007000058174259557,
+                0.0008333317438770897,
+                0.0007000022411365621,
+                0.0005333354949973905,
+                0.000699998664856436
+            ]
+        }
+    ]
+}

+ 359 - 0
src/views/performance/components/chartsCom/lineScatter.vue

@@ -0,0 +1,359 @@
+<!--
+ * @Author: your name
+ * @Date: 2025-07-28 14:00:00
+ * @LastEditTime: 2025-07-29 16:42:29
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/chartsCom/lineScatter.vue
+-->
+
+<template>
+  <div>
+    <!-- 图表控制面板 总图-->
+    <div style="display: flex; align-items: center">
+      <div style="margin-right: 20px; display: flex; align-items: center">
+        <el-select
+          size="small"
+          v-model="color1"
+          @change="updateChartColor"
+          placeholder="选择配色方案"
+          style="width: 200px"
+        >
+          <el-option
+            v-for="(scheme, index) in colorSchemes"
+            :key="index"
+            :label="scheme.label"
+            :value="scheme.colors"
+          >
+            <span
+              v-for="color in scheme.colors.slice(0, 8)"
+              :style="{
+                background: color,
+                width: '20px',
+                height: '20px',
+                display: 'inline-block',
+              }"
+            ></span>
+          </el-option>
+        </el-select>
+        <!-- <span style="margin-left: 10px">自定义颜色</span> -->
+      </div>
+      <div>
+        <el-button size="small" @click="toggleChartType">
+          切换为{{ chartType === "line" ? "面积图" : "折线图" }}
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 图表容器 -->
+    <div
+      v-loading="loading"
+      :id="`bar-chart${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 { colorSchemes } from "@/views/overview/js/colors";
+import { myMixin } from "@/mixins/chartRequestMixin"; // 假设你需要的 mixin
+import { mapState } from "vuex";
+import min_pitch2 from "./json/#34_min_pitch2.json";
+export default {
+  props: {
+    fileAddr: {
+      type: String,
+      default: "",
+    },
+    index: {
+      type: String,
+      default() {
+        return "";
+      },
+    },
+    setUpImgData: {
+      default: () => [],
+      type: Array,
+    },
+  },
+  mixins: [myMixin],
+  data() {
+    return {
+      chartData: {},
+      color1: [], // 默认颜色
+      // 配色方案列表(每个方案是一个颜色数组)
+      colorSchemes: [...colorSchemes],
+      chartType: "line", // 默认图表类型是折线图
+
+      loading: false,
+      isError: false,
+      colors: [...colorSchemes[0].colors],
+      typeLine: ["solid", "solid", "dot", "dot", "dash", "solid"],
+    };
+  },
+  computed: {
+    ...mapState("themes", {
+      themeColor: "themeColor",
+    }),
+  },
+  watch: {
+    themeColor: {
+      handler() {
+        this.color1 = this.themeColor;
+        this.updateChartColor();
+      },
+      deep: true,
+    },
+    setUpImgData: {
+      handler(newType) {
+        this.drawChart();
+      },
+      deep: true,
+    },
+  },
+  mounted() {
+    if (this.fileAddr) {
+      this.$nextTick(() => {
+        this.getData();
+        this.color1 = [
+          "#0000F5",
+          "#377E21",
+          "#0000F5",
+          "#377E21",
+          "#000000",
+          "#F2A93B",
+        ];
+      });
+    }
+  },
+  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.chartData = JSON.parse(JSON.stringify(min_pitch2));
+          // 使用 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 data = [];
+      this.chartData.data.forEach((turbine, index) => {
+        // 判断图表类型,根据类型调整绘制方式
+        const chartConfig = {
+          x: turbine.xData, // X 数据
+          y: turbine.yData, // Y 数据
+          name: turbine.Name, // 使用机组名称
+          type: "scatter",
+          line: {
+            color:
+              this.color1.length > 0
+                ? this.color1[index % this.color1.length]
+                : this.colors[index % this.colors.length], // 为每个机组分配不同的颜色
+          },
+          marker: {
+            color:
+              this.color1.length > 0
+                ? this.color1[index % this.color1.length]
+                : this.colors[index % this.colors.length], // 为每个机组分配不同的颜色
+          },
+          hovertemplate:
+            `${this.chartData.xaixs}:` +
+            ` %{x} <br> ` +
+            `${this.chartData.yaixs}:` +
+            "%{y} <br>",
+        };
+        if (this.chartType === "line") {
+          chartConfig.fill = "none";
+          chartConfig.mode = "lines+markers"; // 如果是折线图
+        } else if (this.chartType === "bar") {
+          chartConfig.fill = "tonexty";
+          // chartConfig.type = "bar"; // 如果是柱状图
+        }
+        data.push(chartConfig);
+      });
+      const layout = {
+        title: {
+          text: this.chartData?.data[0]?.title,
+          font: {
+            size: 16, // 设置标题字体大小(默认 16)
+            weight: "bold",
+          },
+        },
+        xaxis: {
+          title: {
+            text: this.chartData.xaixs || "X轴",
+            standoff: 20,
+            font: {
+              size: 16,
+              color: "#333",
+            },
+          },
+          type: "category",
+          gridcolor: "rgb(255,255,255)",
+          tickcolor: "rgb(255,255,255)",
+          backgroundcolor: "#e5ecf6",
+          showline: true,
+          automargin: true, // ✅ 关键点:防止文字被裁剪,启用自动外边距
+        },
+        yaxis: {
+          title: this.chartData.yaixs || "Y轴", // 纵坐标标题
+          gridcolor: "rgb(255,255,255)",
+          tickcolor: "rgb(255,255,255)",
+          backgroundcolor: "#e5ecf6",
+          // min: -20,
+        },
+        margin: {
+          l: 50,
+          r: 50,
+          t: 50,
+          b: 50,
+        },
+        shapes: [
+          {
+            type: "line",
+            xref: "paper",
+            x0: 0,
+            x1: 1,
+            yref: "y",
+            y0: 0.1,
+            y1: 0.1,
+            line: {
+              color: "red",
+              width: 2,
+              dash: "dash",
+            },
+          },
+          {
+            type: "line",
+            xref: "paper",
+            x0: 0,
+            x1: 1,
+            yref: "y",
+            y0: 0.05,
+            y1: 0.05,
+            line: {
+              color: "#F9DD70",
+              width: 2,
+              dash: "dash",
+            },
+          },
+        ],
+        plot_bgcolor: "#e5ecf6",
+        gridcolor: "#fff",
+        bgcolor: "#e5ecf6", // 设置背景颜色
+        autosize: true, // 开启自适应
+        barmode: this.chartType === "bar" ? "stack" : "group", // 如果是柱状图则启用堆叠
+      };
+      const getChartSetUp = (axisTitle) => {
+        return this.setUpImgData.find((item) => item.text.includes(axisTitle));
+      };
+      const xChartSetUp = getChartSetUp(layout.xaxis.title);
+      if (xChartSetUp) {
+        layout.xaxis.dtick = xChartSetUp.dtick;
+        layout.xaxis.range = [xChartSetUp.min, xChartSetUp.max];
+      }
+      const yChartSetUp = getChartSetUp(layout.yaxis.title);
+      if (yChartSetUp) {
+        layout.yaxis.dtick = yChartSetUp.dtick;
+        layout.yaxis.range = [yChartSetUp.min, yChartSetUp.max];
+      }
+      this.$nextTick(() => {
+        // 使用 Plotly.react 来更新图表
+        Plotly.react(`bar-chart${this.index}`, data, layout, {
+          responsive: true,
+          modeBarButtonsToRemove: [
+            // 移除不需要的工具按钮
+            "lasso2d",
+            "sendDataToCloud",
+            "resetCameraLastSave3d",
+            "resetCameraDefault3d",
+            "resetCameraLastSave",
+            "sendDataToCloud",
+            "zoom2d", // 缩放按钮
+            "zoom3d",
+            "plotlylogo2D",
+            "plotlylogo3D",
+          ],
+          displaylogo: false,
+        }).then(function (gd) {
+          // 获取工具栏按钮
+          const toolbar = gd.querySelector(".modebar");
+          const buttons = toolbar.querySelectorAll(".modebar-btn");
+
+          // 定义一个映射对象,方便修改按钮提示
+          const titleMap = {
+            "Download plot as a png": "保存图片",
+            Autoscale: "缩放",
+            Pan: "平移",
+            "Zoom out": "缩小",
+            "Zoom in": "放大",
+            "Box Select": "选择框操作",
+            "Lasso Select": "套索选择操作",
+            "Reset axes": "重置操作",
+            "Reset camera to default": "重置相机视角",
+            "Turntable rotation": "转台式旋转",
+            "Orbital rotation": "轨道式旋转",
+          };
+          // 遍历所有按钮,修改它们的 title
+          buttons.forEach(function (button) {
+            const dataTitle = button.getAttribute("data-title");
+
+            // 如果标题匹配,修改属性值
+            if (titleMap[dataTitle]) {
+              button.setAttribute("data-title", titleMap[dataTitle]);
+            }
+          });
+        });
+      });
+    },
+
+    // 切换图表类型
+    toggleChartType() {
+      this.chartType = this.chartType === "line" ? "bar" : "line"; // 切换图表类型
+      this.drawChart(); // 重新绘制图表
+    },
+    // 更新图表颜色
+    updateChartColor() {
+      this.drawChart(); // 更新颜色后重新绘制图表
+    },
+    // 根据配色方案设置每个选项的样式
+    getOptionStyle(scheme) {
+      return {
+        background: `linear-gradient(to right, ${scheme
+          .slice(0, 8)
+          .join(", ")})`,
+        color: "#fff",
+        height: "30px",
+        lineHeight: "30px",
+        borderRadius: "0px",
+      };
+    },
+  },
+};
+</script>
+
+<style scoped>
+/* 样式可以根据需求自定义 */
+</style>

+ 7 - 11
vue.config.js

@@ -102,17 +102,13 @@ module.exports = {
           console.log("Proxying /sAlgorithm request to:", proxyReq.path); // 打印代理请求路径
         },
       },
-
-      // // 文佳
-      // "/WJapi": {
-      //   target: process.env.VUE_APP_WJAPIPROXY,
-      //   // target: "http://106.120.102.238:18888",
-      //   changeOrigin: true,
-      //   pathRewrite: {
-      //     "^/WJapi": "",
-      //   },
-      // },
-
+      "/tiles": {
+        target: "http://192.168.50.235", // 或者外网地址
+        changeOrigin: true,
+        pathRewrite: {
+          "^/tiles": "/tiles",
+        },
+      },
       // 王娇娇健康评估
       "/AnalysisMulti": {
         target: process.env.VUE_APP_AnalysisMultiAPIPROXY,