Pārlūkot izejas kodu

新增有功功率、风玫瑰

liujiejie 6 mēneši atpakaļ
vecāks
revīzija
456a91d342

+ 35 - 19
src/views/overview/components/analysis_information/index.vue

@@ -15,7 +15,8 @@
         </div>
         <div>
           该风电场由大唐研究院管理,风场总容量为
-          <span class="headerMessage">{{ fieldInfo.ratedCapacityNumber }} MW
+          <span class="headerMessage"
+            >{{ fieldInfo.ratedCapacityNumber }} MW
           </span>
           ,共安装
           <span class="headerMessage">{{ fieldInfo.engineCount }} 台</span>
@@ -30,7 +31,8 @@
         </div>
         <div>
           分析数据时间跨度为2025年1月20日至2025年2月20日,分析完成时间为2025年1月20日10:10:10。数据分析人
-          <span class="headerMessage"> {{ analysisInfo.updateByName }}</span>。
+          <span class="headerMessage"> {{ analysisInfo.updateByName }}</span
+          >。
         </div>
       </div>
     </div>
@@ -40,26 +42,42 @@
         <div class="box-content-min">
           <h4>完成分析类型:</h4>
 
-          <template v-if="analysisInfo && analysisInfo.analysisTypes?.length > 0">
+          <template
+            v-if="analysisInfo && analysisInfo.analysisTypes?.length > 0"
+          >
             <div class="completeAssetssType">
-              <el-tag v-for="analysis in analysisInfo.analysisTypes" type="warning">{{ analysis.analysisTypeName }}
+              <el-tag
+                v-for="analysis in analysisInfo.analysisTypes"
+                :key="analysis.analysisTypeName"
+                type="warning"
+                >{{ analysis.analysisTypeName }}
               </el-tag>
             </div>
           </template>
 
           <el-empty v-else description="暂无完成分析类型"></el-empty>
-
-
         </div>
 
         <div class="box-content-min">
           <h4>分析完成机组:</h4>
-          <div class="analysisCompletionUnit" v-if="analysisInfo && analysisInfo.windEngineGroups?.length > 0">
-            <div class="itemAnalysisCompletionUnit" v-for="itemData in analysisInfo.windEngineGroups" :key="itemData">
-              <SvgIcons name="WindPower3" class="WindPower3" width="40px" height="42px" color="#222"></SvgIcons>
+          <div
+            class="analysisCompletionUnit"
+            v-if="analysisInfo && analysisInfo.windEngineGroups?.length > 0"
+          >
+            <div
+              class="itemAnalysisCompletionUnit"
+              v-for="itemData in analysisInfo.windEngineGroups"
+              :key="itemData.engineCode"
+            >
+              <SvgIcons
+                name="WindPower3"
+                class="WindPower3"
+                width="40px"
+                height="42px"
+                color="#222"
+              ></SvgIcons>
               <span>{{ itemData.engineName }}#机组</span>
             </div>
-
           </div>
           <el-empty v-else description="暂无分析完成机组"></el-empty>
         </div>
@@ -74,10 +92,7 @@
 <script>
 import Map from "../map/index.vue";
 import { getFieldInfo } from "@/api/overview";
-import {
-  getWindEngineGroup,
-
-} from "@/api/ledger";
+import { getWindEngineGroup } from "@/api/ledger";
 export default {
   name: "AnalysisInformation",
   components: {
@@ -93,10 +108,9 @@ export default {
   data() {
     return {
       fieldInfo: {
-        fieldCode: ''
+        fieldCode: "",
       }, //风场信息
-      fieldCode: '',//风场编号
-
+      fieldCode: "", //风场编号
       analysisInfo: {}, //分析类型编号
       activeNames: ["1", "2", "3"],
       data: [
@@ -108,7 +122,6 @@ export default {
     initBatchCode(newVal, oldVal) {
       console.log(newVal, oldVal, "分析信息内容更新");
       this.getFieldInfoMess();
-
     },
   },
   mounted() {
@@ -119,6 +132,9 @@ export default {
       this.fieldInfo.fieldCode = this.$route.query.fieldCode;
     }
   },
+  created() {
+    this.getFieldInfoMess();
+  },
   methods: {
     async getWindEngList() {
       this.loading = true;
@@ -143,7 +159,7 @@ export default {
           this.fieldInfo = res.data.fieldInfo; //风场信息
           this.analysisInfo = res.data.analysisInfo; //分析类型编号
         }
-      } catch (err) { }
+      } catch (err) {}
     },
     handleChange(val) {
       console.log(val);

+ 296 - 3
src/views/overview/components/cp_trend/index.vue

@@ -1,17 +1,310 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:06:09
- * @LastEditTime: 2025-01-10 09:20:39
+ * @LastEditTime: 2025-01-16 16:14:46
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/cp_trend/index.vue
 -->
+
 <template>
-  <div>风能利用系数时序分析</div>
+  <div class="type-variable">
+    <!-- 风能利用系数时序分析--只有分图不存在总图 -->
+    <div class="left">
+      <FilterChart
+        :windList="windEngineGroupList"
+        @getEnfineList="getEnfineList"
+        @handlePrevious="handlePrevious"
+        @handleNext="handleNext"
+      ></FilterChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          分析风力发电机组的Cp值对于优化其性能和增强效率至关重要:通过测量和分析Cp,可以直观了解风机的效率。Cp值越接近贝兹极限,说明风机的设计和运行越高效。
+        </div>
+        <div style="font-size: 12px; margin-top: 10px">
+          Cp的分析也是监测风机性能的重要手段。如果Cp值出现异常下降,可能预示着机械故障、叶片磨损或其他维护需求。
+        </div>
+      </el-alert>
+      <div class="charts" v-if="diagramRelationsDatas">
+        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
+          <BoxLineCharts
+            :key="itemChart.fieldEngineCode"
+            @getResult="getResult"
+            @changeRequestNum="changeRequestNum"
+            :result="requestResult"
+            :index="indChart"
+            :ref="itemChart.fieldEngineCode"
+            :fileAddr="itemChart.fileAddr"
+          >
+          </BoxLineCharts>
+        </template>
+      </div>
+      <el-empty description="暂无分析记录" v-else></el-empty>
+      <el-tabs value="first">
+        <el-tab-pane label="意见描述" name="first">
+          <TinymceEditor
+            ref="editor"
+            v-model="comment"
+            @input="handleEditorInput($event)"
+            @onClick="onClick"
+          >
+          </TinymceEditor>
+        </el-tab-pane>
+      </el-tabs>
+      <el-row type="flex" class="row-bg" justify="end">
+        <el-col :span="2" style="margin: 20px">
+          <el-button type="primary" size="small">提交评论</el-button>
+        </el-col>
+      </el-row>
+    </div>
+    <div class="right">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
 <script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import BoxLineCharts from "@/views/performance/components/chartsCom/BoxLineCharts.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "cpTrend",
+  components: {
+    DicCard,
+    FilterChart,
+    BoxLineCharts,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图,
+      requestResult: [], // 请求结果
+      requestRecord: [],
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+    };
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    getResult({ index, result }) {
+      console.log(index, result);
+      this.$set(this.requestResult, index, result);
+      // this.requestResult[index] = result
+      this.requestRecord[index] = result;
+    },
+    changeRequestNum(index) {
+      if (index <= 1) {
+        this.$set(this.requestRecord, index, "start");
+        return;
+      }
+      if (index > 1) {
+        if (
+          this.requestRecord.every((item) =>
+            ["success", "error"].includes(item)
+          )
+        ) {
+          this.$set(this.requestRecord, index, "start");
+          this.$set(this.requestResult, index, "start");
+        } else {
+          this.$set(this.requestRecord, index, "start");
+        }
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        console.log(
+          this.initBatchCode,
+          this.analysisTypeCode,
+          "请求详情 分钟级"
+        );
+        // 获取分析详情
+        await this.getAnalysisDetail();
+
+        // 获取风机列表
+        await this.getWindEnfineList(this.initBatchCode, this.analysisTypeCode);
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
+        this.generalFilesDatas =
+          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+        this.diagramRelationsDatas =
+          result.data && result.data[0] && result.data[0].diagramRelations;
+      } catch (err) {
+        console.error("Failed to fetch analysis details:", err);
+      }
+    },
+
+    // 请求风机列表
+    async getWindEnfineList(batchCode, analysisTypeCode) {
+      // console.log("请求风机列表 分钟级");
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: batchCode,
+        analysisTypeCode,
+      });
+      this.windEngineGroupList = resEngineList.data;
+    },
+    handleEditorInput(index, newVal) {
+      // 更新对应的 comment 值
+      // 如果该功能没有实现,可以删除这个方法
+    },
+    //获取选中风机list
+    getEnfineList(data) {
+      this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
+      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+    },
+    //下一条
+    handleNext() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === this.batchCodeList.length - 1) {
+        this.$message.warning("已经是最后一个分析结果了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index + 1]);
+    },
+    //上一条
+    handlePrevious() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === 0) {
+        this.$message.warning("没有上一条了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index - 1]);
+    },
+    onClick() {},
+  },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px;
+    flex: 1;
+  }
+
+  .right {
+    width: 250px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+</style>

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

@@ -147,7 +147,7 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes,
+              : this.fieldEngineCodes.join(","),
         });
         console.log(result, "result");
       } catch (err) {
@@ -170,6 +170,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
       console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
     },
     //下一条

+ 3 - 4
src/views/overview/components/fault_all/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-13 13:56:55
- * @LastEditTime: 2025-01-16 10:01:41
+ * @LastEditTime: 2025-01-16 16:12:21
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/fault_all/index.vue
@@ -295,7 +295,7 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes,
+              : this.fieldEngineCodes.join(","),
         });
         if (
           result.data &&
@@ -346,7 +346,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
-      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+      this.getAnalysisDetail();
     },
     //下一条
     handleNext() {
@@ -374,7 +374,6 @@ export default {
   },
 };
 </script>
-
 <style scoped lang="scss">
 .type-variable {
   display: flex;

+ 3 - 3
src/views/overview/components/fault_unit/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-13 13:56:12
- * @LastEditTime: 2025-01-16 10:02:43
+ * @LastEditTime: 2025-01-16 15:01:03
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/fault_unit/index.vue
@@ -283,7 +283,7 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes,
+              : this.fieldEngineCodes.join(","),
         });
         if (
           result.data &&
@@ -332,7 +332,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
-      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+      this.getAnalysisDetail();
     },
     //下一条
     handleNext() {

+ 4 - 6
src/views/overview/components/min_pitch/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:08:13
- * @LastEditTime: 2025-01-16 09:30:19
+ * @LastEditTime: 2025-01-16 15:47:47
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/min_pitch/index.vue
@@ -32,7 +32,7 @@
         </div>
       </el-alert>
       <div></div>
-
+      <div class="titleCharts">分析分图 :</div>
       <div class="charts" v-if="diagramRelationsDatas">
         <template v-for="(itemChart, indChart) in diagramRelationsDatas">
           <TwoDMarkersChart
@@ -47,9 +47,7 @@
           </TwoDMarkersChart>
         </template>
       </div>
-
       <el-empty description="暂无分析记录" v-else></el-empty>
-
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -223,7 +221,7 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes,
+              : this.fieldEngineCodes.join(","),
         });
         if (
           result.data &&
@@ -269,7 +267,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
-      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+      this.getAnalysisDetail();
     },
     //下一条
     handleNext() {

+ 4 - 4
src/views/overview/components/pitch_tsr_cp/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:09:55
- * @LastEditTime: 2025-01-16 10:03:48
+ * @LastEditTime: 2025-01-16 16:12:31
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/pitch_tsr_cp/index.vue
@@ -9,7 +9,7 @@
 <!-- pitchTsrCp -->
 <template>
   <div class="type-variable">
-    <!-- 动态偏航误差分析--只有分图不存在总图 -->
+    <!-- 变桨和叶尖速比及风能利用系数分析--只有分图不存在总图 -->
     <div class="left">
       <FilterChart
         :windList="windEngineGroupList"
@@ -213,7 +213,7 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes,
+              : this.fieldEngineCodes.join(","),
         });
         if (
           result.data &&
@@ -255,7 +255,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
-      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+      this.getAnalysisDetail();
     },
     //下一条
     handleNext() {

+ 137 - 95
src/views/overview/components/power_curve/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:10:08
- * @LastEditTime: 2025-01-15 16:55:39
+ * @LastEditTime: 2025-01-16 16:13:27
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/power_curve/index.vue
@@ -31,81 +31,72 @@
           在风力发电机组中,功率曲线散点图是一种展示在不同风速下风机产生的功率的工具。这种图表通常以风速为横坐标,以发电机的功率输出为纵坐标。在理想情况下,这些散点应当形成一条清晰的曲线,反映出风速与发电机功率之间的关系。功率曲线是风力发电机性能的关键指标,可以用来评估风机在不同风速条件下的表现。
         </div>
       </el-alert>
-      <el-row class="assetssConent">
-        <!-- 总图 -->
-        <template v-if="generalFilesData.length > 0">
-          <template
-            v-if="generalFilesData[0] !== null && generalFilesData.length !== 0"
-          >
-            <template
-              v-for="(powerCurveDom, ind) in generalFilesData"
-              :style="{ marginTop: '50px' }"
-            >
-              <el-col :span="12">
-                <div class="left">
-                  <el-button
-                    @click="
-                      downLoadCsv(
-                        powerCurveDom && powerCurveDom.powerCurveTableData
-                      )
-                    "
-                    >导出表格数据</el-button
-                  >
-                  <el-table
-                    :data="powerCurveDom && powerCurveDom.powerCurveTableData"
-                    border
-                    max-height="500"
-                    style="width: 100%"
-                    align="center"
-                  >
-                    <el-table-column prop="enginName" label="风机名称">
-                    </el-table-column>
-                    <el-table-column prop="engineTypeName" label="风机机型">
-                    </el-table-column>
-                    <el-table-column prop="xData" label="风速">
-                    </el-table-column>
-                    <el-table-column prop="yData" label="实际功率">
-                    </el-table-column>
-                    <el-table-column prop="contractPowerCurve" label="合同功率">
-                    </el-table-column>
-                  </el-table>
-                </div>
-              </el-col>
-              <el-col :span="12">
-                <div class="right">
-                  <PlotlyCharts
-                    :lineMarkerData="powerCurveDom.chartsData"
-                    :comType="'generalDrawing'"
-                    :inds="`zong${ind}`"
-                  ></PlotlyCharts>
-                </div>
-              </el-col>
-            </template>
-          </template>
-        </template>
-        <!-- 分图 -->
+      <!-- 总图 -->
+      <div class="titleCharts">分析总图 :</div>
+      <div v-if="graphFilesData && graphFilesData.length > 0">
         <template
-          v-if="graphFilesData[0] !== null && graphFilesData.length !== 0"
+          v-for="(powerCurveDom, ind) in generalFilesData"
+          :style="{ marginTop: '50px' }"
+        >
+          <el-row class="charts">
+            <el-col :span="12" :key="ind + 'leftTable'">
+              <div class="leftTable">
+                <el-button
+                  @click="
+                    downLoadCsv(
+                      powerCurveDom && powerCurveDom.powerCurveTableData
+                    )
+                  "
+                  >导出表格数据</el-button
+                >
+                <el-table
+                  :data="powerCurveDom.powerCurveTableData"
+                  border
+                  max-height="500"
+                  style="width: 100%"
+                  align="center"
+                >
+                  <el-table-column prop="enginName" label="风机名称">
+                  </el-table-column>
+                  <el-table-column prop="engineTypeName" label="风机机型">
+                  </el-table-column>
+                  <el-table-column prop="xData" label="风速"> </el-table-column>
+                  <el-table-column prop="yData" label="实际功率">
+                  </el-table-column>
+                  <el-table-column prop="contractPowerCurve" label="合同功率">
+                  </el-table-column>
+                </el-table>
+              </div>
+            </el-col>
+            <el-col :span="12" :key="ind + 'rightTable'">
+              <div class="rightTable">
+                <PlotlyCharts
+                  :lineMarkerData="powerCurveDom.chartsData"
+                  :comType="'generalDrawing'"
+                  :inds="`zong${ind}`"
+                ></PlotlyCharts>
+              </div>
+            </el-col>
+          </el-row>
+        </template>
+      </div>
+      <el-empty v-else description="暂无总图"></el-empty>
+      <!-- 分图 -->
+      <div class="titleCharts">分析分图 :</div>
+      <template v-if="graphFilesData && graphFilesData.length > 0">
+        <div
+          class="graphFilesData"
+          v-for="(powerCurveDom, ind) in graphFilesData"
         >
-          <template v-for="(powerCurveDom, ind) in graphFilesData">
+          <el-row class="charts">
             <el-col
               :span="12"
+              :key="ind + 'powerCurveDom' + 'leftTable'"
               v-if="
-                powerCurveDom &&
-                formInfo.fieldEngineCode ===
-                  powerCurveDom.chartsData.formInfoFieldEngineCode &&
-                powerCurveDom.powerCurveTableData.length > 0
+                powerCurveDom && powerCurveDom.powerCurveTableData.length > 0
               "
             >
-              <div class="left">
-                <!-- <el-button
-                        @click="
-                          downLoadCsv(
-                            powerCurveDom && powerCurveDom.powerCurveTableData
-                          )
-                        "
-                        >导出表格数据</el-button
-                      > -->
+              <div class="leftTable">
                 <el-table
                   :data="powerCurveDom && powerCurveDom.powerCurveTableData"
                   border
@@ -127,14 +118,12 @@
             </el-col>
             <el-col
               v-if="
-                powerCurveDom &&
-                formInfo.fieldEngineCode ===
-                  powerCurveDom.chartsData.formInfoFieldEngineCode &&
-                powerCurveDom.powerCurveTableData.length > 0
+                powerCurveDom && powerCurveDom.powerCurveTableData.length > 0
               "
+              :key="ind + 'powerCurveDom' + 'rightTable'"
               :span="12"
             >
-              <div class="right">
+              <div class="rightTable">
                 <PlotlyCharts
                   :lineMarkerData="powerCurveDom.chartsData"
                   :comType="'graph'"
@@ -142,10 +131,13 @@
                 ></PlotlyCharts>
               </div>
             </el-col>
-            <el-empty v-else description="该机组暂无分图"></el-empty>
-          </template>
-        </template>
-      </el-row>
+            <el-col v-else :span="24">
+              <el-empty description="暂无分图"></el-empty>
+            </el-col>
+          </el-row>
+        </div>
+      </template>
+      <el-empty v-else description="暂无分图"></el-empty>
 
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
@@ -165,7 +157,12 @@
       </el-row>
     </div>
     <div class="right">
-      <DicCard></DicCard>
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="'fault'"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
     </div>
   </div>
 </template>
@@ -212,8 +209,9 @@ export default {
       comment: "",
       options: [],
       generalFilesData: [],
-      graphChartData: {},
       graphFilesData: [],
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
     };
   },
   watch: {
@@ -263,9 +261,23 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes,
+              : this.fieldEngineCodes.join(","),
         });
-        console.log(result, "result");
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
         this.generalFilesData = [];
         this.graphFilesData = [];
         const generalFiles = result.data[0]?.generalFiles || [];
@@ -274,17 +286,17 @@ export default {
           "总图"
         );
         //分图数据
-        const graphChartData = await this.filterJsonData(
+        this.graphFilesData = await this.filterJsonData(
           result.data[0]?.diagramRelations || [],
           "分图"
         );
+
         // 过滤掉 null 或没有 chartsData 的项
         this.generalFilesData = generalFilesData.filter(
           (item) => item && item.chartsData
         );
-        this.graphFilesData = graphChartData.filter(
-          (item) => item && item.chartsData
-        );
+        console.log(this.generalFilesData, "总图");
+        console.log(this.graphFilesData, "分图");
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }
@@ -313,17 +325,14 @@ export default {
                 return {
                   chartsData: {
                     ...resultChartsData.data,
-
-                    formInfoFieldEngineCode: this.formInfo.fieldEngineCode,
+                    formInfoFieldEngineCode: item.fieldEngineCode,
                   },
                   powerCurveTableData: this.creatPowerCurveTableData(
                     resultChartsData.data
                   )
                     .filter((val) => val !== undefined)
                     .filter(
-                      (item) =>
-                        item?.enginName === this.formInfo.fieldEngineCode ||
-                        item?.enginCode === this.formInfo.fieldEngineCode
+                      (items) => items?.enginCode === item.fieldEngineCode
                     ),
                 };
               }
@@ -335,6 +344,30 @@ export default {
         })
       );
     },
+    getFileType(url) {
+      // 使用 URL 对象解析 URL
+      // 获取路径名部分
+      let pathname = url.split("/").pop();
+      // 截取路径名,去除加密乱码字符部分
+      const index = pathname.indexOf(".html");
+      if (index !== -1) {
+        pathname = pathname.slice(0, index + 5); // '.html' 的长度是 5
+      } else {
+        pathname = pathname.slice(0, pathname.indexOf(".png") + 4); // '.png' 的长度是 4
+      }
+      // 正则表达式匹配图片扩展名
+      const imageExtensions = /\.(png|jpg|jpeg|gif|bmp|svg)$/i;
+      // 正则表达式匹配 HTML 扩展名
+      const htmlExtensions = /\.html?$/i;
+
+      if (imageExtensions.test(pathname)) {
+        return "image";
+      } else if (htmlExtensions.test(pathname)) {
+        return "html";
+      } else {
+        return "unknown";
+      }
+    },
     creatPowerCurveTableData(data) {
       // 风机名称\风机机型\风速\合同功率\实际功率
       // xData--风速
@@ -388,9 +421,7 @@ export default {
         headers.join(","),
         ...data.map((row) => row.join(",")),
       ].join("\n");
-      const fileName = this.windEngineGroupList.filter(
-        (item) => item.engineCode === this.formInfo.fieldEngineCode
-      );
+
       downLoadCsvFile(csvContent, "风机有功功率数据");
       // downLoadCsvFile(csvContent, fileName[0].engineName);
     },
@@ -410,7 +441,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
-      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+      this.getAnalysisDetail();
     },
     //下一条
     handleNext() {
@@ -457,4 +488,15 @@ export default {
     overflow: hidden;
   }
 }
+.rightTable {
+  width: 100%;
+}
+.charts {
+  margin: 10px 0;
+}
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
 </style>

+ 465 - 3
src/views/overview/components/tsr_trend/index.vue

@@ -1,17 +1,479 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:10:39
- * @LastEditTime: 2025-01-10 09:14:38
+ * @LastEditTime: 2025-01-16 16:46:39
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/tsr_trend/index.vue
 -->
+
 <template>
-  <div>叶尖速比时序分析</div>
+  <div class="type-variable">
+    <!-- 叶尖速比时序分析--只有分图不存在总图 -->
+    <div class="left">
+      <FilterChart
+        :windList="windEngineGroupList"
+        @getEnfineList="getEnfineList"
+        @handlePrevious="handlePrevious"
+        @handleNext="handleNext"
+      ></FilterChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          分析风力发电机组的Cp值对于优化其性能和增强效率至关重要:通过测量和分析Cp,可以直观了解风机的效率。Cp值越接近贝兹极限,说明风机的设计和运行越高效。
+        </div>
+        <div style="font-size: 12px; margin-top: 10px">
+          Cp的分析也是监测风机性能的重要手段。如果Cp值出现异常下降,可能预示着机械故障、叶片磨损或其他维护需求。
+        </div>
+      </el-alert>
+      <div class="charts" v-if="diagramRelationsDatas">
+        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
+          <BoxMarkersCharts
+            :key="itemChart.fieldEngineCode"
+            @getResult="getResult"
+            @changeRequestNum="changeRequestNum"
+            :result="requestResult"
+            :index="indChart"
+            :ref="itemChart.fieldEngineCode"
+            :fileAddr="itemChart.fileAddr"
+            :chartData="chartData"
+          >
+          </BoxMarkersCharts>
+        </template>
+      </div>
+      <el-empty description="暂无分析记录" v-else></el-empty>
+      <el-tabs value="first">
+        <el-tab-pane label="意见描述" name="first">
+          <TinymceEditor
+            ref="editor"
+            v-model="comment"
+            @input="handleEditorInput($event)"
+            @onClick="onClick"
+          >
+          </TinymceEditor>
+        </el-tab-pane>
+      </el-tabs>
+      <el-row type="flex" class="row-bg" justify="end">
+        <el-col :span="2" style="margin: 20px">
+          <el-button type="primary" size="small">提交评论</el-button>
+        </el-col>
+      </el-row>
+    </div>
+    <div class="right">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
 <script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import BoxMarkersCharts from "@/views/performance/components/chartsCom/BoxMarkersCharts.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+
 export default {
   name: "tsrTrend",
+  components: {
+    DicCard,
+    FilterChart,
+    BoxMarkersCharts,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      chartData: {
+        analysisTypeCode: "叶尖速比时序分析",
+        engineCode: "WEM00026",
+        engineTypeName: "",
+        xaixs: "时间",
+        yaixs: "叶尖速比",
+        data: [
+          {
+            engineName: "#01",
+            engineCode: "WOG00935",
+            title: "机组-#01",
+            xData: [
+              "2023-10-01",
+              "2023-10-01",
+              "2023-10-01",
+              "2023-10-02",
+              "2023-10-02",
+              "2023-10-02",
+              "2023-10-02",
+              "2023-10-02",
+              "2023-12-06",
+              "2023-12-06",
+              "2023-12-06",
+              "2023-12-06",
+              "2023-12-06",
+              "2023-12-31",
+              "2023-12-31",
+              "2023-12-31",
+              "2023-12-31",
+              "2023-12-31",
+              "2023-12-31",
+            ],
+            yData: [
+              15.543049499999999, 13.862719824324321, 13.497911407894735,
+              14.247794979227915, 14.967381000000001, 12.827075038461539,
+              13.432265000000001,
+            ],
+            color: "lightgray",
+            width: 2,
+            type: "box_plot",
+            medians: {
+              x: [
+                "2023-10-01",
+                "2023-10-02",
+                "2023-10-03",
+                "2023-10-04",
+                "2023-10-05",
+                "2023-10-06",
+                "2023-10-07",
+                "2023-10-08",
+                "2023-10-09",
+                "2023-10-10",
+                "2023-10-11",
+                "2023-10-12",
+                "2023-10-13",
+                "2023-10-14",
+                "2023-10-15",
+                "2023-10-16",
+                "2023-10-17",
+                "2023-10-18",
+                "2023-10-19",
+                "2023-10-20",
+                "2023-10-21",
+                "2023-10-22",
+                "2023-10-23",
+                "2023-10-24",
+                "2023-10-25",
+                "2023-10-26",
+                "2023-10-27",
+                "2023-10-28",
+                "2023-10-29",
+                "2023-10-30",
+                "2023-10-31",
+                "2023-11-01",
+                "2023-11-02",
+                "2023-11-03",
+                "2023-11-04",
+                "2023-11-05",
+                "2023-11-06",
+                "2023-11-07",
+                "2023-11-08",
+                "2023-11-09",
+                "2023-11-10",
+                "2023-11-11",
+                "2023-11-12",
+                "2023-11-13",
+                "2023-11-14",
+                "2023-11-15",
+                "2023-11-16",
+                "2023-11-17",
+                "2023-11-18",
+                "2023-11-19",
+                "2023-11-20",
+                "2023-11-21",
+                "2023-11-22",
+                "2023-11-23",
+                "2023-11-24",
+                "2023-11-25",
+                "2023-11-26",
+                "2023-11-27",
+                "2023-11-28",
+                "2023-11-29",
+                "2023-11-30",
+                "2023-12-01",
+                "2023-12-02",
+                "2023-12-03",
+                "2023-12-04",
+                "2023-12-05",
+                "2023-12-06",
+                "2023-12-07",
+                "2023-12-08",
+                "2023-12-09",
+                "2023-12-10",
+                "2023-12-11",
+                "2023-12-12",
+                "2023-12-13",
+                "2023-12-14",
+                "2023-12-15",
+                "2023-12-16",
+                "2023-12-18",
+                "2023-12-19",
+                "2023-12-24",
+                "2023-12-25",
+                "2023-12-26",
+                "2023-12-27",
+                "2023-12-28",
+                "2023-12-29",
+                "2023-12-30",
+                "2023-12-31",
+              ],
+              y: [
+                12.061625714285714, 12.395244357750359, 11.442673266175094,
+                10.36922885625, 11.26786431617647, 12.788870794117651,
+                11.760086202205983, 12.355811707317073, 11.887048926997425,
+                11.56872207295834, 12.827075038461539, 12.827075038461539,
+                11.671397888696765, 11.369452874999999, 11.667242439889808,
+                12.20136406097561, 11.633858755813954, 12.664707, 12.5063981625,
+                9.904450346153844, 11.961112166666664, 14.713409602941177,
+                13.520430445945946, 13.520430445945946, 13.164629644736843,
+                11.945121375, 13.164629644736843, 13.164629644736843,
+                12.536452761102844, 13.314179153846153, 12.827075038461539,
+                11.369452874999999, 13.164629644736843, 14.293026471428572,
+                13.520430445945946, 11.420851848214285, 10.97608045539225,
+                11.746974608695654, 12.08018303574669, 12.20136406097561,
+                13.520430445945946, 11.910854542081818, 11.209977141891892,
+                11.772826225352112, 12.26579435260202, 11.850547264285714,
+                8.194810411764706, 9.570488812499999, 11.45028304109589,
+                13.520430445945946, 13.324327156249998, 11.683638147887326,
+                11.547232852941178, 11.690498094778956, 11.8731628125,
+                11.50377658039225, 12.559168830392247, 11.814091821757081,
+                11.182666105361738, 12.199092772058824, 10.883732578125,
+                11.209977141891892, 13.691575135135134, 13.895997572333401,
+                13.164629644736843, 13.520430445945946, 11.418212162100799,
+                10.782115418918918, 10.472739292609424, 10.116320835365855,
+                10.659461724999998, 10.421998468750001, 9.713248529513232,
+                10.232523066441793, 8.379173986952123, 8.798638547368421,
+                6.52254407794278, 10.26608825, 10.1317656, 9.950841214285715,
+                10.403152178571428, 10.310370442307692, 12.5063981625,
+                12.5063981625, 11.116798366666666, 11.167968899999998,
+                10.4579787094475,
+              ],
+              mode: "markers",
+              color: "orange",
+              size: 3,
+            },
+          },
+        ],
+      },
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图,
+      requestResult: [], // 请求结果
+      requestRecord: [],
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+    };
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    getResult({ index, result }) {
+      console.log(index, result);
+      this.$set(this.requestResult, index, result);
+      // this.requestResult[index] = result
+      this.requestRecord[index] = result;
+    },
+    changeRequestNum(index) {
+      if (index <= 1) {
+        this.$set(this.requestRecord, index, "start");
+        return;
+      }
+      if (index > 1) {
+        if (
+          this.requestRecord.every((item) =>
+            ["success", "error"].includes(item)
+          )
+        ) {
+          this.$set(this.requestRecord, index, "start");
+          this.$set(this.requestResult, index, "start");
+        } else {
+          this.$set(this.requestRecord, index, "start");
+        }
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        console.log(
+          this.initBatchCode,
+          this.analysisTypeCode,
+          "请求详情 分钟级"
+        );
+        // 获取分析详情
+        await this.getAnalysisDetail();
+
+        // 获取风机列表
+        await this.getWindEnfineList(this.initBatchCode, this.analysisTypeCode);
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
+        this.generalFilesDatas =
+          result.data && result.data[0] && result.data[0].generalFiles; //总图数据
+        this.diagramRelationsDatas =
+          result.data && result.data[0] && result.data[0].diagramRelations;
+      } catch (err) {
+        console.error("Failed to fetch analysis details:", err);
+      }
+    },
+
+    // 请求风机列表
+    async getWindEnfineList(batchCode, analysisTypeCode) {
+      // console.log("请求风机列表 分钟级");
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: batchCode,
+        analysisTypeCode,
+      });
+      this.windEngineGroupList = resEngineList.data;
+    },
+    handleEditorInput(index, newVal) {
+      // 更新对应的 comment 值
+      // 如果该功能没有实现,可以删除这个方法
+    },
+    //获取选中风机list
+    getEnfineList(data) {
+      this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
+      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+    },
+    //下一条
+    handleNext() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === this.batchCodeList.length - 1) {
+        this.$message.warning("已经是最后一个分析结果了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index + 1]);
+    },
+    //上一条
+    handlePrevious() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === 0) {
+        this.$message.warning("没有上一条了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index - 1]);
+    },
+    onClick() {},
+  },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px;
+    flex: 1;
+  }
+
+  .right {
+    width: 250px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+</style>

+ 64 - 6
src/views/overview/components/wind_direction_frequency/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:11:12
- * @LastEditTime: 2025-01-14 17:21:35
+ * @LastEditTime: 2025-01-16 16:13:19
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/wind_direction_frequency/index.vue
@@ -16,7 +16,33 @@
         @handlePrevious="handlePrevious"
         @handleNext="handleNext"
       ></FilterChart>
-      <WindRoseChart></WindRoseChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          风向玫瑰图是一种表示某地不同风向出现频率分布的图表。
+        </div>
+      </el-alert>
+      <div class="titleCharts">分析分图 :</div>
+      <div class="charts" v-if="diagramRelationsDatas">
+        <template v-for="(itemChart, indChart) in diagramRelationsDatas">
+          <WindRoseChart
+            :key="itemChart.fieldEngineCode + indChart"
+            :inds="indChart"
+            :ref="itemChart.fieldEngineCode"
+            :fileAddr="itemChart.fileAddr"
+          ></WindRoseChart>
+        </template>
+      </div>
+      <el-empty description="暂无分析记录" v-else></el-empty>
+
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -35,7 +61,12 @@
       </el-row>
     </div>
     <div class="right">
-      <DicCard></DicCard>
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
     </div>
   </div>
 </template>
@@ -80,6 +111,8 @@ export default {
       fieldEngineCodes: [], //选中风机
       generalFilesDatas: [], //总图
       diagramRelationsDatas: [], //分图
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
     };
   },
   watch: {
@@ -129,12 +162,32 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes,
+              : this.fieldEngineCodes.join(","),
         });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
         this.generalFilesDatas =
           result.data && result.data[0] && result.data[0].generalFiles; //总图数据
         this.diagramRelationsDatas =
-          result.data && result.data[0] && result.data[0].diagramRelations;
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
+        console.log(this.diagramRelationsDatas, "this.diagramRelationsDatas");
       } catch (err) {
         console.error("Failed to fetch analysis details:", err);
       }
@@ -156,7 +209,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
-      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+      this.getAnalysisDetail();
     },
     //下一条
     handleNext() {
@@ -202,4 +255,9 @@ export default {
     overflow: hidden;
   }
 }
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
 </style>

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

@@ -128,7 +128,7 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes,
+              : this.fieldEngineCodes.join(","),
         });
         this.generalFilesDatas =
           result.data && result.data[0] && result.data[0].generalFiles; //总图数据
@@ -155,7 +155,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
-      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+      this.getAnalysisDetail();
     },
     //下一条
     handleNext() {

+ 377 - 3
src/views/overview/components/yaw_error/index.vue

@@ -1,17 +1,391 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:24:14
- * @LastEditTime: 2025-01-10 09:24:37
+ * @LastEditTime: 2025-01-16 16:12:50
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/yaw_error/index.vue
 -->
+
 <template>
-  <div>静态偏航误差分析</div>
+  <div class="type-variable">
+    <!-- 静态偏航误差分析 -->
+    <div class="left">
+      <FilterChart
+        :windList="windEngineGroupList"
+        @getEnfineList="getEnfineList"
+        @handlePrevious="handlePrevious"
+        @handleNext="handleNext"
+      ></FilterChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          静态偏航误差过大,导致风轮不能精准对风,会造成发电损失,例如10°的静态偏航误差导致2.6%的发电损失,且风速较低的风场往往出现更多的发电损失;此外静态偏航误差过大,不仅会影响机组的功率输出,还会引起叶片气动弹性波动,增加机组的额外载荷。因此,定期检测机组的静态偏航误差,并及时校正,对于改善机组发电性能和机组运行安全都有很重要的意义。
+        </div>
+      </el-alert>
+      <div v-if="zongFaultCsvData.length > 0">
+        <FaultAll
+          :faultTypes="
+            zongFaultCsvData &&
+            zongFaultCsvData[0] &&
+            zongFaultCsvData[0].data.map((item) => item.fault_detail)
+          "
+          :faultCounts="
+            zongFaultCsvData &&
+            zongFaultCsvData[0] &&
+            zongFaultCsvData[0].data.map((item) => item.count)
+          "
+          :faultDurations="
+            zongFaultCsvData &&
+            zongFaultCsvData[0] &&
+            zongFaultCsvData[0].data.map((item) => item.fault_time_sum)
+          "
+          :zongFaultCsvData="zongFaultCsvData"
+        ></FaultAll>
+        <template v-for="(itemCsv, indCsv) in zongFaultCsvData">
+          <el-table
+            :key="indCsv + 'indCsv'"
+            :data="filteredData(itemCsv)"
+            border
+            style="width: 100%"
+            align="center"
+          >
+            <el-table-column prop="engine_name" label="风机名称">
+            </el-table-column>
+            <el-table-column prop="yaw_error1" label="误差值">
+            </el-table-column>
+            <el-table-column align="right">
+              <template slot="header" slot-scope="scope">
+                <el-input
+                  v-model="search"
+                  size="mini"
+                  placeholder="输入故障类型关键字搜索"
+                />
+              </template>
+            </el-table-column>
+          </el-table>
+        </template>
+      </div>
+      <el-empty description="暂无分析记录" v-else></el-empty>
+      <el-tabs value="first">
+        <el-tab-pane label="意见描述" name="first">
+          <TinymceEditor
+            ref="editor"
+            v-model="comment"
+            @input="handleEditorInput($event)"
+            @onClick="onClick"
+          >
+          </TinymceEditor>
+        </el-tab-pane>
+      </el-tabs>
+      <el-row type="flex" class="row-bg" justify="end">
+        <el-col :span="2" style="margin: 20px">
+          <el-button type="primary" size="small">提交评论</el-button>
+        </el-col>
+      </el-row>
+    </div>
+    <div class="right">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="'fault'"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
 <script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import FaultAll from "@/views/performance/components/chartsCom/FaultAll.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
+import Papa from "papaparse";
+import axios from "axios";
 export default {
   name: "yaw_error",
+  components: {
+    DicCard,
+    FilterChart,
+    FaultAll,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      search: "",
+      form: {
+        value2: "",
+      },
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      zongFaultCsvHeader: [],
+      zongFaultCsvData: [],
+      fenFaultCsvHeader: [],
+      fenFaultCsvData: [],
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+    };
+  },
+  computed: {
+    // 根据搜索关键字过滤数据
+    filteredData() {
+      return (itemCsv) => {
+        // 如果有搜索关键词,则过滤数据
+        if (this.search) {
+          return itemCsv.data.filter((item) => {
+            return item.fault_detail
+              .toLowerCase()
+              .includes(this.search.toLowerCase());
+          });
+        }
+        // 没有搜索关键词时返回所有数据
+        return itemCsv.data;
+      };
+    },
+    filteredFenData() {
+      return (itemCsv) => {
+        // 如果有搜索关键词,则过滤数据
+        if (this.searchFen) {
+          return itemCsv.data.filter((item) => {
+            return item.wind_turbine_name
+              .toLowerCase()
+              .includes(this.searchFen.toLowerCase());
+          });
+        }
+        // 没有搜索关键词时返回所有数据
+        return itemCsv.data;
+      };
+    },
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 封装的获取 CSV 数据方法
+    fetchCsvData(analysisType, url) {
+      axios
+        .get(url, { responseType: "blob" }) // 确保数据以 blob 格式返回
+        .then((response) => {
+          const reader = new FileReader();
+          reader.onload = (e) => {
+            const csvText = e.target.result;
+            Papa.parse(csvText, {
+              header: true, // 使用 CSV 第一行作为键
+              complete: (result) => {
+                // 根据分析类型设置不同的数据
+                if (analysisType === "yaw_error") {
+                  if (Object.keys(result.data[0]).includes("engine_name")) {
+                    //总图故障统计展示
+                    this.zongFaultCsvHeader.push(Object.keys(result.data[0]));
+                    this.zongFaultCsvData.push({
+                      data: result.data
+                        .filter((row) => Object.keys(row).length)
+                        .slice(0, result.data.length - 1),
+                    });
+                  } else {
+                    //分机型故障统计处理
+                    this.fenFaultCsvHeader.push(Object.keys(result.data[0]));
+                    this.fenFaultCsvData.push({
+                      data: result.data
+                        .filter((row) => Object.keys(row).length)
+                        .slice(0, result.data.length - 1),
+                    });
+                  }
+                }
+              },
+              error: (error) => {
+                console.error("CSV 解析错误:", error);
+              },
+            });
+          };
+          reader.readAsText(response.data); // 读取 blob 数据
+        })
+        .catch((error) => {
+          console.error("无法获取 CSV 文件:", error);
+        });
+    },
+    // 合并后的函数,处理数据请求
+    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: "fault",
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
+
+        if (result.data && result.data[0] && result.data[0].generalFiles) {
+          result.data[0].generalFiles.map((item) => {
+            if (item.fileAddr) {
+              this.zongFaultCsvHeader = [];
+              this.zongFaultCsvData = [];
+              this.fetchCsvData("yaw_error", item.fileAddr);
+            }
+          });
+        } else {
+          this.zongFaultCsvHeader = [];
+          this.zongFaultCsvData = [];
+        }
+      } catch (err) {
+        console.error("Failed to fetch analysis details:", err);
+      }
+    },
+    // 请求风机列表
+    async getWindEnfineList(batchCode, analysisTypeCode) {
+      // console.log("请求风机列表 分钟级");
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: batchCode,
+        analysisTypeCode,
+      });
+      this.windEngineGroupList = resEngineList.data;
+    },
+    handleEditorInput(index, newVal) {
+      // 更新对应的 comment 值
+      // 如果该功能没有实现,可以删除这个方法
+    },
+    //获取选中风机list
+    getEnfineList(data) {
+      this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
+    },
+    //下一条
+    handleNext() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === this.batchCodeList.length - 1) {
+        this.$message.warning("已经是最后一个分析结果了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index + 1]);
+    },
+    //上一条
+    handlePrevious() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === 0) {
+        this.$message.warning("没有上一条了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index - 1]);
+    },
+    onClick() {},
+  },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px;
+    flex: 1;
+  }
+
+  .right {
+    width: 250px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+</style>

+ 4 - 4
src/views/overview/components/yaw_error_density/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:26:12
- * @LastEditTime: 2025-01-16 10:04:45
+ * @LastEditTime: 2025-01-16 15:01:54
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/yaw_error_density/index.vue
@@ -27,7 +27,7 @@
           </div>
         </template>
         <div style="font-size: 12px; margin-top: 10px">
-          风能利用系数可以表示为变桨角度和叶尖速比的函数。每一个确定的桨距角,都存在一个最大风力利用系数,随着桨距角的变大,最大风力利用系数降低,其对应的叶尖速比也降低。此分析可以看出机组的发电情况表现
+          动态偏航误差分析是对机组偏航对风角度的分布情况进行统计及可视化展示,对风角度分布对称性较差的机组需要关注其偏航系统对风异常原因
         </div>
       </el-alert>
       <div class="charts" v-if="diagramRelationsDatas">
@@ -212,7 +212,7 @@ export default {
           fieldEngineCodes:
             this.fieldEngineCodes.length === 0
               ? undefined
-              : this.fieldEngineCodes,
+              : this.fieldEngineCodes.join(","),
         });
         if (
           result.data &&
@@ -254,7 +254,7 @@ export default {
     //获取选中风机list
     getEnfineList(data) {
       this.fieldEngineCodes = data;
-      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+      this.getAnalysisDetail();
     },
     //下一条
     handleNext() {

+ 3 - 0
src/views/overview/index.vue

@@ -112,6 +112,9 @@ export default {
         }
       });
     },
+    analysisTypeCode(newVal) {
+      console.log(newVal, "分析类型 ");
+    },
   },
   created() {
     this.getTreeData();

+ 4 - 110
src/views/performance/components/PlotlyCharts.vue

@@ -132,6 +132,7 @@ export default {
   },
   methods: {
     updateCharts() {
+      console.log(this.lineMarkerData, "this.lineMarkerData");
       this.powerCurveData.turbines =
         this.lineMarkerData.data?.filter(
           (item) => item.enginName !== "合同功率曲线"
@@ -185,9 +186,10 @@ export default {
     initializeEngineCharts() {
       const fentuCharts = this.powerCurveData.turbines.filter(
         (item) =>
-          item.enginCode === this.lineMarkerData?.formInfoFieldEngineCode ||
-          item.enginName === this.lineMarkerData?.formInfoFieldEngineCode
+          item.enginCode === this.lineMarkerData?.formInfoFieldEngineCode
       );
+      console.log(this.powerCurveData.turbines, "this.powerCurveData.turbines");
+      console.log(fentuCharts, "fentuCharts");
       if (fentuCharts[0]?.enginName || fentuCharts[0]?.enginCode) {
         const highlightedData = [];
         const nonHighlightedData = [];
@@ -240,114 +242,6 @@ export default {
         Plotly.newPlot(`chart-${this.inds}`, data, layout);
       }
     },
-
-    // initializeEngineCharts() {
-    //   console.log(this.lineMarkerData, "enginName");
-    //   const fentuCharts = this.powerCurveData.turbines.filter(
-    //     (item) =>
-    //       item.enginCode === this.lineMarkerData?.formInfoFieldEngineCode ||
-    //       item.enginName === this.lineMarkerData?.formInfoFieldEngineCode
-    //   );
-    //   const data = [];
-    //   const layout = {
-    //     title:
-    //       fentuCharts[0]?.enginName ||
-    //       fentuCharts[0]?.enginCode + "风机有功功率曲线分析",
-    //     plot_bgcolor: this.config.lableConfig.plot_bgcolor,
-    //     xaxis: this.config.lableConfig.xaxis,
-    //     yaxis: this.config.lableConfig.yaxis,
-    //     legend: this.config.lableConfig.legend,
-    //   };
-
-    //   // 先渲染其他的风机数据
-    //   this.powerCurveData.turbines.forEach((turbine, index) => {
-    //     const isHighlighted =
-    //       turbine?.enginCode === this.lineMarkerData?.formInfoFieldEngineCode ||
-    //       turbine?.enginName === this.lineMarkerData?.formInfoFieldEngineCode;
-
-    //     // 这里将高亮的风机与其他风机分开
-    //     data.push({
-    //       x: turbine.xData,
-    //       y: turbine.yData.map((val) => (val !== null ? val : 0.0)),
-    //       mode: "lines",
-    //       name: turbine.enginName,
-    //       line: {
-    //         color: isHighlighted ? "#1c77b3" : "#d3d3d3", // 高亮的线条使用指定颜色
-    //       },
-    //     });
-    //   });
-
-    //   // 将高亮的风机放在最后,确保它显示在其他线条上面
-    //   const highlightedData = data.filter(
-    //     (item) => item.line.color === "#1c77b3"
-    //   );
-    //   const nonHighlightedData = data.filter(
-    //     (item) => item.line.color !== "#1c77b3"
-    //   );
-
-    //   // 把高亮的线条放在数据的最后
-    //   data.length = 0;
-    //   data.push(...nonHighlightedData, ...highlightedData); // 将非高亮的线条先添加,最后添加高亮线条
-
-    //   // 添加合同功率曲线
-    //   data.push({
-    //     x: this.powerCurveData.contractPowerCurve[0].xData,
-    //     y: this.powerCurveData.contractPowerCurve[0].yData,
-    //     mode: "lines+markers",
-    //     name: this.powerCurveData.contractPowerCurve[0].enginName,
-    //     line: {
-    //       color: "red",
-    //     },
-    //   });
-
-    //   Plotly.newPlot(`chart-${this.inds}`, data, layout);
-    // },
-
-    // initializeEngineCharts() {
-    //   console.log(this.lineMarkerData, "enginName");
-    //   const fentuCharts = this.powerCurveData.turbines.filter(
-    //     (item) =>
-    //       item.enginCode === this.lineMarkerData?.formInfoFieldEngineCode ||
-    //       item.enginName === this.lineMarkerData?.formInfoFieldEngineCode
-    //   );
-    //   const data = [];
-    //   const layout = {
-    //     title:
-    //       fentuCharts[0]?.enginName ||
-    //       fentuCharts[0]?.enginCode + "风机有功功率曲线分析",
-    //     plot_bgcolor: this.config.lableConfig.plot_bgcolor,
-    //     xaxis: this.config.lableConfig.xaxis,
-    //     yaxis: this.config.lableConfig.yaxis,
-    //     legend: this.config.lableConfig.legend,
-    //   };
-    //   this.powerCurveData.turbines.forEach((turbine, index) => {
-    //     const isHighlighted =
-    //       turbine?.enginCode === this.lineMarkerData?.formInfoFieldEngineCode ||
-    //       turbine?.enginName === this.lineMarkerData?.formInfoFieldEngineCode;
-
-    //     data.push({
-    //       x: turbine.xData,
-    //       y: turbine.yData.map((val) => (val !== null ? val : 0.0)),
-    //       mode: "lines",
-    //       name: turbine.enginName,
-    //       line: {
-    //         color: isHighlighted ? "#1c77b3" : "#d3d3d3", // 如果是高亮的线条,设置为指定颜色
-    //         // 使用 layer 属性来控制堆叠顺序
-    //         layer: isHighlighted ? "above traces" : "below traces", // 高亮线条显示在其他线条上面
-    //       },
-    //     });
-    //   });
-    //   data.push({
-    //     x: this.powerCurveData.contractPowerCurve[0].xData,
-    //     y: this.powerCurveData.contractPowerCurve[0].yData,
-    //     mode: "lines+markers",
-    //     name: this.powerCurveData.contractPowerCurve[0].enginName,
-    //     line: {
-    //       color: "red",
-    //     },
-    //   });
-    //   Plotly.newPlot(`chart-${this.inds}`, data, layout);
-    // },
   },
 };
 </script>

+ 3 - 3
src/views/performance/components/chartsCom/BoxLineCharts.vue

@@ -1,15 +1,15 @@
 <!--
  * @Author: your name
  * @Date: 2024-09-11 14:32:51
- * @LastEditTime: 2024-10-08 14:09:36
+ * @LastEditTime: 2025-01-16 11:07:58
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/BoxLineCharts.vue
 -->
 <template>
   <div>
-    boxLineCharts
-    <h1>额定功率和风速分析</h1>
+    <!-- boxLineCharts -->
+    <!-- <h1>额定功率和风速分析</h1> -->
     <div
       :id="`plotDivAbove25-${inds}`"
       style="width: 100%; height: 550px"

+ 99 - 8
src/views/performance/components/chartsCom/BoxMarkersCharts.vue

@@ -1,17 +1,17 @@
 <!--
  * @Author: your name
  * @Date: 2024-09-11 14:36:31
- * @LastEditTime: 2024-09-11 14:40:15
- * @LastEditors: milo-MacBook-Pro.local
+ * @LastEditTime: 2025-01-16 16:50:04
+ * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/BoxMarkersCharts.vue
 -->
-<template>
-  <div>
-    BoxMarkersCharts
+<!-- <template>
+  <div> -->
+<!-- BoxMarkersCharts
     <h1>叶尖速比时序分析</h1>
-    <h1>风能利用系数时序分析</h1>
-    <div :id="`chart-${inds}`" style="width: 100%; height: 550px"></div>
+    <h1>风能利用系数时序分析</h1> -->
+<!-- <div :id="`chart-${inds}`" style="width: 100%; height: 550px"></div>
   </div>
 </template>
 <script>
@@ -34,4 +34,95 @@ export default {
   },
 };
 </script>
-<style scoped></style>
+<style scoped></style> -->
+<template>
+  <div ref="chart" style="width: 100%; height: 400px"></div>
+</template>
+
+<script>
+import Plotly from "plotly.js-dist";
+
+export default {
+  name: "BoxPlotChart",
+  props: {
+    chartData: {
+      type: Object,
+      required: true,
+    },
+  },
+  watch: {
+    chartData: {
+      deep: true,
+      // immediate: true,
+      handler(newData) {
+        if (newData) {
+          this.drawChart(newData);
+        }
+      },
+    },
+  },
+  created() {
+    // this.drawChart(this.chartData);
+  },
+  methods: {
+    drawChart(data) {
+      const traces = [];
+
+      // Box plot trace
+      data.data.forEach((engine) => {
+        traces.push({
+          x: engine.xData,
+          y: engine.yData,
+          type: "box",
+          name: engine.title,
+          marker: {
+            color: engine.color || "lightgray",
+          },
+          line: {
+            width: engine.width || 2,
+          },
+        });
+
+        // Median points trace
+        traces.push({
+          x: engine.medians.x,
+          y: engine.medians.y,
+          mode: engine.medians.mode || "markers",
+          marker: {
+            color: engine.medians.color || "orange",
+            size: engine.medians.size || 5,
+          },
+          name: `${engine.title} 中位点`,
+        });
+      });
+
+      const layout = {
+        title: data.analysisTypeCode || "箱线图",
+        xaxis: {
+          title: data.xaixs || "X轴",
+        },
+        yaxis: {
+          title: data.yaixs || "Y轴",
+        },
+        showlegend: true,
+        margin: {
+          l: 50,
+          r: 50,
+          t: 50,
+          b: 50,
+        },
+      };
+
+      Plotly.newPlot(this.$refs.chart, traces, layout, { responsive: true });
+    },
+  },
+};
+</script>
+
+<style scoped>
+/* 确保图表容器的大小适应 */
+div {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 79 - 84
src/views/performance/components/chartsCom/WindRoseChart.vue

@@ -1,114 +1,107 @@
 <template>
   <div>
-    <!-- <h1>风向玫瑰分析</h1> -->
     <div :id="`plotDiv-${inds}`" style="width: 100%; height: 550px"></div>
   </div>
 </template>
 
 <script>
 import Plotly from "plotly.js-dist";
-
+import axios from "axios";
 export default {
   props: {
-    data: {
-      type: Array,
-      default: () => [
-        { windSpeed: 2.5, windDirection: 30 },
-        { windSpeed: 4.8, windDirection: 60 },
-        { windSpeed: 7.2, windDirection: 90 },
-        { windSpeed: 9.1, windDirection: 120 },
-        { windSpeed: 3.5, windDirection: 150 },
-        { windSpeed: 5.6, windDirection: 180 },
-        { windSpeed: 8.3, windDirection: 210 },
-        { windSpeed: 6.4, windDirection: 240 },
-        { windSpeed: 2.9, windDirection: 270 },
-        { windSpeed: 7.7, windDirection: 300 },
-        { windSpeed: 3.2, windDirection: 330 },
-        { windSpeed: 4.0, windDirection: 360 },
-        { windSpeed: 5.1, windDirection: 45 },
-        { windSpeed: 6.9, windDirection: 75 },
-        { windSpeed: 8.6, windDirection: 105 },
-        { windSpeed: 7.0, windDirection: 135 },
-        { windSpeed: 4.5, windDirection: 165 },
-        { windSpeed: 9.0, windDirection: 195 },
-        { windSpeed: 3.8, windDirection: 225 },
-        { windSpeed: 5.9, windDirection: 255 },
-        { windSpeed: 7.5, windDirection: 285 },
-        { windSpeed: 6.0, windDirection: 315 },
-        { windSpeed: 2.7, windDirection: 345 },
-      ],
+    fileAddr: {
+      default: "",
+      type: String,
     },
+
     inds: {
       type: [Number, String],
       default: 1,
     },
   },
+  data() {
+    return {
+      // 数据结构
+      chartData: {},
+    };
+  },
+  watch: {
+    chartData: {
+      deep: true,
+      handler(v) {
+        if (v) {
+          this.renderChart();
+        }
+      },
+    },
+  },
   mounted() {
-    this.renderChart();
+    this.getData();
   },
   methods: {
-    renderChart() {
-      const bins = [0, 3, 6, 9, Infinity];
-      const speedLabels = ["[0,3)", "[3,6)", "[6,9)", ">=9"];
-      const windDirections = Array.from({ length: 16 }, (_, i) => i * 22.5);
-      const directionLabels = [
-        "N",
-        "NNE",
-        "NE",
-        "ENE",
-        "E",
-        "ESE",
-        "SE",
-        "SSE",
-        "S",
-        "SSW",
-        "SW",
-        "WSW",
-        "W",
-        "WNW",
-        "NW",
-        "NNW",
-      ];
-      const colorscale = {
-        "[0,3)": "#FBFDD4",
-        "[3,6)": "#C0E2BA",
-        "[6,9)": "#57A3BF",
-        ">=9": "#1A2971",
-      };
-
-      const speedBins = this.data.map((item) => {
-        for (let i = 0; i < bins.length - 1; i++) {
-          if (item.windSpeed >= bins[i] && item.windSpeed < bins[i + 1]) {
-            return speedLabels[i];
-          }
+    async getData() {
+      if (this.fileAddr !== "") {
+        try {
+          const resultChartsData = await axios.get(this.fileAddr);
+          this.chartData = resultChartsData.data;
+          console.log(this.chartData, "this.chartData");
+          this.renderChart();
+          this.$emit("getResult", { index: this.index, result: "success" });
+        } catch (error) {
+          this.$emit("getResult", { index: this.index, result: "error" });
         }
-        return ">=9";
+      }
+    },
+    renderChart() {
+      const { axes, data, analysisTypeCode } = this.chartData;
+      // 从数据中提取 windSpeedRange 和动态生成 speedLabels 和 colorscale
+      const windSpeedRanges = new Set();
+      data.forEach((engine) => {
+        engine.windRoseData.forEach((item) => {
+          windSpeedRanges.add(item.windSpeedRange);
+        });
       });
-
-      const directionBins = this.data.map((item) => {
-        return windDirections.find(
-          (d, i) =>
-            item.windDirection >= d &&
-            item.windDirection < windDirections[i + 1]
-        );
+      const speedLabels = Array.from(windSpeedRanges).sort(); // 动态范围值
+      const colors = [
+        "#FBFDD4",
+        "#C0E2BA",
+        "#57A3BF",
+        "#1A2971",
+        "#FF6F61",
+        "#FFC300",
+        "#6A0572",
+      ]; // 可扩展颜色列表
+      const colorscale = {};
+      speedLabels.forEach((label, index) => {
+        colorscale[label] = colors[index % colors.length];
       });
 
+      // 定义风向的 16 等分
+      const windDirections = Array.from({ length: 16 }, (_, i) => i * 22.5);
+
+      // 数据聚合
       const counts = {};
       speedLabels.forEach((speedLabel) => {
-        counts[speedLabel] = Array(windDirections.length - 1).fill(0);
+        counts[speedLabel] = Array(windDirections.length).fill(0);
       });
 
-      this.data.forEach((item, i) => {
-        const speedLabel = speedBins[i];
-        const directionBin = directionBins[i];
-        const index = windDirections.indexOf(directionBin);
-        counts[speedLabel][index]++;
+      data.forEach((engine) => {
+        engine.windRoseData.forEach((item) => {
+          const { windDirection, windSpeedRange } = item;
+          const index = windDirections.findIndex(
+            (dir, i) =>
+              windDirection >= dir && windDirection < windDirections[i + 1]
+          );
+
+          if (index !== -1 && counts[windSpeedRange]) {
+            counts[windSpeedRange][index] += item.frequency;
+          }
+        });
       });
 
+      // 构建 traces
       const traces = speedLabels.map((speedLabel) => {
-        const percentage = counts[speedLabel].map(
-          (c) => (c / this.data.length) * 100
-        );
+        const percentage = counts[speedLabel];
         return {
           r: percentage,
           theta: windDirections,
@@ -124,26 +117,28 @@ export default {
         };
       });
 
+      // 图表布局
       const layout = {
-        title: "Wind Rose",
+        title: `${analysisTypeCode} - ${data[0]?.enginName} `,
         plot_bgcolor: "#e5ecf6",
         polar: {
           bgcolor: "#e5ecf6",
           radialaxis: {
+            title: { text: axes.radial },
             gridcolor: "rgb(255,255,255)",
             showgrid: true,
             linecolor: "rgb(255,255,255)",
           },
           angularaxis: {
+            title: { text: axes.angular },
             tickvals: windDirections,
-            ticktext: directionLabels,
             gridcolor: "rgb(255,255,255)",
             tickcolor: "rgb(255,255,255)",
             linecolor: "rgb(255,255,255)",
           },
         },
         showlegend: true,
-        legend: { title: { text: "Wind Speed" } },
+        legend: { title: { text: axes.levelname } },
       };
 
       Plotly.newPlot(`plotDiv-${this.inds}`, traces, layout);

+ 167 - 0
zzzz.json

@@ -0,0 +1,167 @@
+{
+  "analysisTypeCode": "叶尖速比时序分析",
+  "engineCode": "WEM00026",
+  "engineTypeName": "",
+  "xaixs": "时间",
+  "yaixs": "叶尖速比",
+  "data": [
+    {
+      "engineName": "#01",
+      "engineCode": "WOG00935",
+      "title": "机组-#01",
+      "xData": [
+        "2023-10-01",
+        "2023-10-01",
+        "2023-10-01",
+        "2023-10-02",
+        "2023-10-02",
+        "2023-10-02",
+        "2023-10-02",
+        "2023-10-02",
+        "2023-12-06",
+        "2023-12-06",
+        "2023-12-06",
+        "2023-12-06",
+        "2023-12-06",
+        "2023-12-31",
+        "2023-12-31",
+        "2023-12-31",
+        "2023-12-31",
+        "2023-12-31",
+        "2023-12-31"
+      ],
+      "yData": [
+        15.543049499999999, 13.862719824324321, 13.497911407894735,
+        14.247794979227915, 14.967381000000001, 12.827075038461539,
+        13.432265000000001
+      ],
+      "color": "lightgray",
+      "width": 2,
+      "type": "box_plot",
+      "medians": {
+        "x": [
+          "2023-10-01",
+          "2023-10-02",
+          "2023-10-03",
+          "2023-10-04",
+          "2023-10-05",
+          "2023-10-06",
+          "2023-10-07",
+          "2023-10-08",
+          "2023-10-09",
+          "2023-10-10",
+          "2023-10-11",
+          "2023-10-12",
+          "2023-10-13",
+          "2023-10-14",
+          "2023-10-15",
+          "2023-10-16",
+          "2023-10-17",
+          "2023-10-18",
+          "2023-10-19",
+          "2023-10-20",
+          "2023-10-21",
+          "2023-10-22",
+          "2023-10-23",
+          "2023-10-24",
+          "2023-10-25",
+          "2023-10-26",
+          "2023-10-27",
+          "2023-10-28",
+          "2023-10-29",
+          "2023-10-30",
+          "2023-10-31",
+          "2023-11-01",
+          "2023-11-02",
+          "2023-11-03",
+          "2023-11-04",
+          "2023-11-05",
+          "2023-11-06",
+          "2023-11-07",
+          "2023-11-08",
+          "2023-11-09",
+          "2023-11-10",
+          "2023-11-11",
+          "2023-11-12",
+          "2023-11-13",
+          "2023-11-14",
+          "2023-11-15",
+          "2023-11-16",
+          "2023-11-17",
+          "2023-11-18",
+          "2023-11-19",
+          "2023-11-20",
+          "2023-11-21",
+          "2023-11-22",
+          "2023-11-23",
+          "2023-11-24",
+          "2023-11-25",
+          "2023-11-26",
+          "2023-11-27",
+          "2023-11-28",
+          "2023-11-29",
+          "2023-11-30",
+          "2023-12-01",
+          "2023-12-02",
+          "2023-12-03",
+          "2023-12-04",
+          "2023-12-05",
+          "2023-12-06",
+          "2023-12-07",
+          "2023-12-08",
+          "2023-12-09",
+          "2023-12-10",
+          "2023-12-11",
+          "2023-12-12",
+          "2023-12-13",
+          "2023-12-14",
+          "2023-12-15",
+          "2023-12-16",
+          "2023-12-18",
+          "2023-12-19",
+          "2023-12-24",
+          "2023-12-25",
+          "2023-12-26",
+          "2023-12-27",
+          "2023-12-28",
+          "2023-12-29",
+          "2023-12-30",
+          "2023-12-31"
+        ],
+        "y": [
+          12.061625714285714, 12.395244357750359, 11.442673266175094,
+          10.36922885625, 11.26786431617647, 12.788870794117651,
+          11.760086202205983, 12.355811707317073, 11.887048926997425,
+          11.56872207295834, 12.827075038461539, 12.827075038461539,
+          11.671397888696765, 11.369452874999999, 11.667242439889808,
+          12.20136406097561, 11.633858755813954, 12.664707, 12.5063981625,
+          9.904450346153844, 11.961112166666664, 14.713409602941177,
+          13.520430445945946, 13.520430445945946, 13.164629644736843,
+          11.945121375, 13.164629644736843, 13.164629644736843,
+          12.536452761102844, 13.314179153846153, 12.827075038461539,
+          11.369452874999999, 13.164629644736843, 14.293026471428572,
+          13.520430445945946, 11.420851848214285, 10.97608045539225,
+          11.746974608695654, 12.08018303574669, 12.20136406097561,
+          13.520430445945946, 11.910854542081818, 11.209977141891892,
+          11.772826225352112, 12.26579435260202, 11.850547264285714,
+          8.194810411764706, 9.570488812499999, 11.45028304109589,
+          13.520430445945946, 13.324327156249998, 11.683638147887326,
+          11.547232852941178, 11.690498094778956, 11.8731628125,
+          11.50377658039225, 12.559168830392247, 11.814091821757081,
+          11.182666105361738, 12.199092772058824, 10.883732578125,
+          11.209977141891892, 13.691575135135134, 13.895997572333401,
+          13.164629644736843, 13.520430445945946, 11.418212162100799,
+          10.782115418918918, 10.472739292609424, 10.116320835365855,
+          10.659461724999998, 10.421998468750001, 9.713248529513232,
+          10.232523066441793, 8.379173986952123, 8.798638547368421,
+          6.52254407794278, 10.26608825, 10.1317656, 9.950841214285715,
+          10.403152178571428, 10.310370442307692, 12.5063981625, 12.5063981625,
+          11.116798366666666, 11.167968899999998, 10.4579787094475
+        ],
+        "mode": "markers",
+        "color": "orange",
+        "size": 3
+      }
+    }
+  ]
+}