Sfoglia il codice sorgente

链条页面图表

liujiejie 6 mesi fa
parent
commit
d41d3268c5

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

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

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

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

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

@@ -1,17 +1,283 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 17:55:01
- * @LastEditTime: 2025-01-10 09:20:15
+ * @LastEditTime: 2025-01-20 13:23:31
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/data_integrity_second/index.vue
 -->
+
 <template>
-  <div>秒级钟级SCADA数据完整度分析</div>
+  <div class="type-variable">
+    <!-- 秒级钟级SCADA数据完整度分析 -->
+    <div class="left">
+      <FilterChart
+        :windList="windEngineGroupList"
+        @getEnfineList="getEnfineList"
+        @handlePrevious="handlePrevious"
+        @handleNext="handleNext"
+      ></FilterChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          风电机组SCADA数据完整度分析是对风电场运行数据质量进行评估的关键环节。
+        </div>
+        <div style="font-size: 12px; margin-top: 10px">
+          数据完整度分析可以帮助识别数据缺失、异常或噪声,确保所采集数据的准确性和连贯性。这对于后续的风电机组运行分析和故障诊断至关重要。
+        </div>
+        <div style="font-size: 12px; margin-top: 10px">
+          数据完整度分析是根据数据统计周期内数据总行数与期望数据总行数的比值计算出来的。
+        </div>
+      </el-alert>
+
+      <HeatmapCharts></HeatmapCharts>
+      <el-tabs value="first">
+        <el-tab-pane label="意见描述" name="first">
+          <TinymceEditor
+            ref="editor"
+            v-model="comment"
+            @input="handleEditorInput($event)"
+            @onClick="onClick"
+          >
+          </TinymceEditor>
+        </el-tab-pane>
+      </el-tabs>
+      <el-row type="flex" class="row-bg" justify="end">
+        <el-col :span="2" style="margin: 20px">
+          <el-button type="primary" size="small" @click="handleComment"
+            >提交评论</el-button
+          >
+        </el-col>
+      </el-row>
+    </div>
+    <div class="right">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
 <script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import HeatmapCharts from "@/views/performance/components/chartsCom/HeatmapCharts.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
 export default {
   name: "DataIntegritySecond",
+  components: {
+    DicCard,
+    FilterChart,
+    HeatmapCharts,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+
+      commentDescriptionVos: [], //评论列表
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图,
+      editableTabs: [],
+    };
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        console.log(
+          this.initBatchCode,
+          this.analysisTypeCode,
+          "请求详情 分钟级"
+        );
+        // 获取分析详情
+        await this.getAnalysisDetail();
+
+        // 获取风机列表
+        await this.getWindEnfineList(this.initBatchCode, this.analysisTypeCode);
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
+        this.generalFilesDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
+        this.diagramRelationsDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
+      } catch (err) {
+        console.error("Failed to fetch analysis details:", err);
+      }
+    },
+    // 请求风机列表
+    async getWindEnfineList(batchCode, analysisTypeCode) {
+      // console.log("请求风机列表 分钟级");
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: batchCode,
+        analysisTypeCode,
+      });
+      this.windEngineGroupList = resEngineList.data;
+    },
+    handleEditorInput(index, newVal) {
+      // 更新对应的 comment 值
+      // 如果该功能没有实现,可以删除这个方法
+    },
+    //获取选中风机list
+    getEnfineList(data) {
+      this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
+      console.log(this.fieldEngineCodes, "this.fieldEngineCodes");
+    },
+    //下一条
+    handleNext() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === this.batchCodeList.length - 1) {
+        this.$message.warning("已经是最后一个分析结果了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index + 1]);
+    },
+    //上一条
+    handlePrevious() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === 0) {
+        this.$message.warning("没有上一条了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index - 1]);
+    },
+    onClick() {},
+  },
 };
 </script>
-<style scoped lang="scss"></style>
+
+<style scoped lang="scss">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+  .left {
+    width: 30%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px;
+    flex: 1;
+  }
+  .right {
+    width: 250px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+</style>

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

@@ -1,17 +1,300 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:09:25
- * @LastEditTime: 2025-01-10 09:19:31
+ * @LastEditTime: 2025-01-20 13:16:21
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/pitch_generator_speed/index.vue
 -->
+
 <template>
-  <div>变桨和发电机转速协调性分析</div>
+  <div class="type-variable">
+    <!-- 变桨和发电机转速协调性分析--只有分图不存在总图 -->
+    <div class="left">
+      <FilterChart
+        :windList="windEngineGroupList"
+        @getEnfineList="getEnfineList"
+        @handlePrevious="handlePrevious"
+        @handleNext="handleNext"
+      ></FilterChart>
+      <el-alert type="info" :closable="false">
+        <template v-slot:title>
+          <div style="display: flex; align-items: center">
+            <i
+              class="el-icon-info"
+              style="font-size: 20px; margin-right: 5px"
+            ></i>
+            <h3>分析说明:</h3>
+          </div>
+        </template>
+        <div style="font-size: 12px; margin-top: 10px">
+          在风力发电机组中,最小桨距角是指叶片相对于风向的最小角度。桨距角是风力发电机关键的可调参数之一,它决定了叶片与风的接触角度,从而影响着风机的功率输出和效率。最小桨距角通常在风速较低时使用,目的是最大化捕获风能,从而提高风机的启动性能和低风速下的能量输出。
+        </div>
+      </el-alert>
+      <div></div>
+      <div class="titleCharts">分析分图 :</div>
+      <VirtualList
+        :list="diagramRelationsDatas"
+        keyField="fieldEngineCode"
+        :itemSize="452"
+        v-slot="{ item, index }"
+      >
+        <TwoDMarkersChart
+          :key="item.fieldEngineCode"
+          :index="index"
+          :ref="item.fieldEngineCode"
+          :fileAddr="item.fileAddr"
+        ></TwoDMarkersChart>
+      </VirtualList>
+      <el-tabs value="first">
+        <el-tab-pane label="意见描述" name="first">
+          <TinymceEditor
+            ref="editor"
+            v-model="comment"
+            @input="handleEditorInput($event)"
+            @onClick="onClick"
+          >
+          </TinymceEditor>
+        </el-tab-pane>
+      </el-tabs>
+      <el-row type="flex" class="row-bg" justify="end">
+        <el-col :span="2" style="margin: 20px">
+          <el-button type="primary" size="small" @click="handleComment"
+            >提交评论</el-button
+          >
+        </el-col>
+      </el-row>
+    </div>
+    <div class="right">
+      <DicCard
+        :batchCode="initBatchCode"
+        :analysisTypeCode="analysisTypeCode"
+        :commentDescriptionVos="commentDescriptionVos"
+      >
+      </DicCard>
+    </div>
+  </div>
 </template>
 <script>
+import DicCard from "@/views/overview/components/dicCard/index.vue";
+import FilterChart from "@/views/overview/components/filterChart/index.vue";
+import TwoDMarkersChart from "@/views/performance/components/chartsCom/TwoDMarkersChart.vue";
+import TinymceEditor from "@/components/Tinymce.vue";
+import {
+  analysisDetail,
+  queryAnalysisedEngine,
+  analysisCommentEdit,
+} from "@/api/performance";
+
 export default {
   name: "pitchGeneratorSpeed",
+  components: {
+    DicCard,
+    FilterChart,
+    TwoDMarkersChart,
+    TinymceEditor,
+  },
+  props: {
+    initBatchCode: {
+      default: "",
+      type: String,
+    },
+    analysisTypeCode: {
+      default: "",
+      type: String,
+    },
+    batchCodeList: {
+      default: "",
+      type: Array,
+    },
+  },
+  data() {
+    return {
+      form: {
+        value2: "",
+      },
+      windEngineGroupList: [], //批次风机列表
+      fieldEngineCodes: [], //选中风机
+      comment: "",
+      options: [],
+      generalFilesDatas: [], //总图
+      diagramRelationsDatas: [], //分图,
+      commentDescriptionVos: [], //评论列表
+      editableTabs: [],
+    };
+  },
+  watch: {
+    initBatchCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+    analysisTypeCode(newVal) {
+      if (newVal) {
+        this.fetchData(); // 调用合并后的函数
+      }
+    },
+  },
+  mounted() {
+    if (this.initBatchCode && this.analysisTypeCode) {
+      this.fetchData(); // 调用合并后的函数
+    }
+  },
+  methods: {
+    async handleComment() {
+      try {
+        await analysisCommentEdit({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          commentList: this.editableTabs.map((item) => {
+            return {
+              commentTypeCode: item.commentTypeCode,
+              comment: item.commentTypeName === "分析评论" ? this.comment : "",
+            };
+          }),
+        });
+        this.$message({
+          type: "success",
+          message: "保存成功",
+        });
+        this.comment = "";
+        this.getAnalysisDetail();
+      } catch (e) {
+        console.error(e);
+        this.loading = false;
+      }
+    },
+    onSubmit() {
+      console.log("submit!");
+    },
+    // 合并后的函数,处理数据请求
+    async fetchData() {
+      try {
+        console.log(
+          this.initBatchCode,
+          this.analysisTypeCode,
+          "请求详情 分钟级"
+        );
+        // 获取分析详情
+        await this.getAnalysisDetail();
+
+        // 获取风机列表
+        await this.getWindEnfineList(this.initBatchCode, this.analysisTypeCode);
+      } catch (err) {
+        console.error("Failed to fetch data:", err);
+      }
+    },
+    // 获取分析详情接口
+    async getAnalysisDetail() {
+      try {
+        const result = await analysisDetail({
+          batchCode: this.initBatchCode,
+          analysisTypeCode: this.analysisTypeCode,
+          fieldEngineCodes:
+            this.fieldEngineCodes.length === 0
+              ? undefined
+              : this.fieldEngineCodes.join(","),
+        });
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentTypeRelations
+        ) {
+          this.editableTabs = result.data[0].commentTypeRelations;
+        }
+        //当前评论展示获取
+        if (
+          result.data &&
+          result.data[0] &&
+          result.data[0].commentDescriptionVos
+        ) {
+          this.commentDescriptionVos = result.data[0].commentDescriptionVos;
+        }
+        this.generalFilesDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].generalFiles &&
+          result.data[0].generalFiles.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          ); //总图数据
+        this.diagramRelationsDatas =
+          result.data &&
+          result.data[0] &&
+          result.data[0].diagramRelations.filter((item) =>
+            item.fileAddr.endsWith(".json")
+          );
+      } catch (err) {
+        console.error("Failed to fetch analysis details:", err);
+      }
+    },
+
+    // 请求风机列表
+    async getWindEnfineList(batchCode, analysisTypeCode) {
+      // console.log("请求风机列表 分钟级");
+      const resEngineList = await queryAnalysisedEngine({
+        batchCode: batchCode,
+        analysisTypeCode,
+      });
+      this.windEngineGroupList = resEngineList.data;
+    },
+    handleEditorInput(index, newVal) {
+      // 更新对应的 comment 值
+      // 如果该功能没有实现,可以删除这个方法
+    },
+    //获取选中风机list
+    getEnfineList(data) {
+      this.fieldEngineCodes = data;
+      this.getAnalysisDetail();
+    },
+    //下一条
+    handleNext() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === this.batchCodeList.length - 1) {
+        this.$message.warning("已经是最后一个分析结果了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index + 1]);
+    },
+    //上一条
+    handlePrevious() {
+      const index = this.batchCodeList.findIndex(
+        (item) => item === this.initBatchCode
+      );
+      if (index === 0) {
+        this.$message.warning("没有上一条了");
+        return;
+      }
+      this.$emit("setInitBathCode", this.batchCodeList[index - 1]);
+    },
+    onClick() {},
+  },
 };
 </script>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.type-variable {
+  display: flex;
+  height: 90%;
+  overflow: hidden;
+
+  .left {
+    width: 30%;
+    height: 100%;
+    overflow: auto;
+    padding: 20px;
+    flex: 1;
+  }
+
+  .right {
+    width: 250px;
+    height: 100%;
+    overflow: hidden;
+  }
+}
+.titleCharts {
+  font-size: 16px;
+  font-weight: 500;
+  margin-top: 20px;
+}
+</style>

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

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

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

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-09 18:10:47
- * @LastEditTime: 2025-01-20 09:19:28
+ * @LastEditTime: 2025-01-20 09:45:37
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/rated_power_windspeed/index.vue
@@ -41,7 +41,7 @@
         <BoxLineCharts
           :key="item.batchCode + index"
           :index="index"
-          :ref="item.batchCode + indChart"
+          :ref="item.batchCode + index"
           :fileAddr="item.fileAddr"
         >
         </BoxLineCharts>

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

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

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

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

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

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

+ 23 - 19
src/views/overview/components/tsr_cp_power/index.vue

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:10:24
- * @LastEditTime: 2025-01-20 09:23:09
+ * @LastEditTime: 2025-01-20 12:12:06
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/tsr_cp_power/index.vue
@@ -32,36 +32,38 @@
         </div>
       </el-alert>
 
-      <div class="titleCharts">分析总图 :</div>
-      <VirtualList
-        :list="generalFilesDatas"
-        keyField="batchCode"
-        :itemSize="452"
-        v-slot="{ item, index }"
+      <div
+        class="titleCharts"
+        v-if="generalFilesDatas && generalFilesDatas.length > 0"
       >
+        分析总图 :
+      </div>
+      <div v-for="(item, index) in generalFilesDatas">
         <lineAndChildLine
           :key="item.batchCode + index"
-          :inds="index"
+          :index="index"
           :ref="item.batchCode"
           :fileAddr="item.fileAddr"
         >
         </lineAndChildLine>
-      </VirtualList>
-      <div class="titleCharts">分析分图 :</div>
-      <VirtualList
-        :list="diagramRelationsDatas"
-        keyField="fieldEngineCode"
-        :itemSize="452"
-        v-slot="{ item, index }"
+      </div>
+      <div
+        class="titleCharts"
+        v-if="diagramRelationsDatas && diagramRelationsDatas.length > 0"
       >
-        <lineAndChildLine
+        分析分图 :
+      </div>
+      <div v-for="(item, index) in diagramRelationsDatas">
+        <lineChartsFen
           :key="item.fieldEngineCode + index"
-          :inds="index"
+          :index="index"
           :ref="item.fieldEngineCode"
+          :fieldEngineCode="item.fieldEngineCode"
           :fileAddr="item.fileAddr"
         >
-        </lineAndChildLine>
-      </VirtualList>
+        </lineChartsFen>
+      </div>
+
       <el-tabs value="first">
         <el-tab-pane label="意见描述" name="first">
           <TinymceEditor
@@ -95,6 +97,7 @@
 import DicCard from "@/views/overview/components/dicCard/index.vue";
 import FilterChart from "@/views/overview/components/filterChart/index.vue";
 import lineAndChildLine from "@/views/performance/components/chartsCom/lineAndChildLine.vue";
+import lineChartsFen from "@/views/performance/components/chartsCom/lineChartsFen.vue";
 import TinymceEditor from "@/components/Tinymce.vue";
 import { analysisDetail, queryAnalysisedEngine } from "@/api/performance";
 
@@ -104,6 +107,7 @@ export default {
     DicCard,
     FilterChart,
     lineAndChildLine,
+    lineChartsFen,
     TinymceEditor,
   },
   props: {

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

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

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

@@ -1,7 +1,7 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-10 09:26:12
- * @LastEditTime: 2025-01-20 09:23:35
+ * @LastEditTime: 2025-01-20 10:04:27
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/overview/components/yaw_error_density/index.vue

+ 16 - 7
src/views/performance/components/chartsCom/3DDrawingChart.vue

@@ -1,16 +1,21 @@
 <!--
  * @Author: your name
  * @Date: 2025-01-17 19:04:52
- * @LastEditTime: 2025-01-20 09:37:15
+ * @LastEditTime: 2025-01-20 10:41:41
  * @LastEditors: bogon
  * @Description: In User Settings Edit
  * @FilePath: /performance-test/src/views/performance/components/chartsCom/3DDrawingChart.vue
 -->
 <template>
-  <div
-    :id="`plotly-3d-chart-` + index"
-    style="width: 100%; height: 400px"
-  ></div>
+  <div style="height: 452px">
+    <div
+      :id="`plotly-3d-chart-` + index"
+      style="width: 100%; height: 400px"
+    ></div>
+    <div v-loading="loading" ref="plotlyChart" style="height: 400px">
+      <el-empty v-if="isError" description="请求失败"></el-empty>
+    </div>
+  </div>
 </template>
 
 <script>
@@ -102,11 +107,15 @@ export default {
         try {
           this.loading = true;
           this.cancelToken = axios.CancelToken.source();
-          console.log(this.cancelToken);
+          console.log(this.fileAddr, "3D url");
           const resultChartsData = await axios.get(this.fileAddr, {
             cancelToken: this.cancelToken.token,
           });
-          console.log(resultChartsData);
+          // console.log(
+          //   resultChartsData.data,
+          //   JSON.parse(resultChartsData.data),
+          //   "解析3D数据"
+          // );
           this.chartData = resultChartsData.data;
           this.renderChart();
           this.isError = false;

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

@@ -20,9 +20,6 @@
           <el-button size="small" @click="setChartType('line')"
             >折线图</el-button
           >
-          <el-button size="small" @click="setChartType('bar')"
-            >柱状图</el-button
-          >
         </div>
       </div>
       <!-- <div v-loading="$parent.requestRecord[index] === 'start'"> -->

+ 51 - 72
src/views/performance/components/chartsCom/lineAndChildLine.vue

@@ -1,31 +1,16 @@
-<!--
- * @Author: your name
- * @Date: 2024-09-11 14:28:15
- * @LastEditTime: 2024-09-11 14:40:37
- * @LastEditors: milo-MacBook-Pro.local
- * @Description: In User Settings Edit
- * @FilePath: /performance-test/src/views/performance/components/chartsCom/lineAndChildLine.vue
--->
-<!-- <template>
-  <div>
-    lineAndChildLine
-    <h1>有功功率曲线分析</h1>
-    <h1>叶尖速比和有功功率分析</h1>
-    <h1>叶尖速比-Cp-功率分析</h1>
-    <h1>风能利用系数和有功功率分析</h1>
-    <h1>风能利用系数和风速分析</h1>
-    <h1>叶尖速比和风速分析</h1>
-    <div :id="`chart-${inds}`" style="width: 100%; height: 550px"></div>
-  </div>
-</template> -->
 <template>
   <div>
-    <!-- 图表控制面板 -->
+    <!-- 图表控制面板 总图-->
     <div style="display: flex; align-items: center">
-      <div style="margin-right: 20px; display: flex; align-items: center">
-        <el-color-picker size="small" v-model="color1" show-alpha @change="updateChartColor"></el-color-picker>
+      <!-- <div style="margin-right: 20px; display: flex; align-items: center">
+        <el-color-picker
+          size="small"
+          v-model="color1"
+          show-alpha
+          @change="updateChartColor"
+        ></el-color-picker>
         <span style="margin-left: 10px">自定义颜色</span>
-      </div>
+      </div> -->
       <div>
         <el-button size="small" @click="toggleChartType">
           切换为{{ chartType === "line" ? "柱状图" : "折线图" }}
@@ -34,7 +19,11 @@
     </div>
 
     <!-- 图表容器 -->
-    <div v-loading="loading" :id="`bar-chart${inds}`" style="width: 100%; height: 400px">
+    <div
+      v-loading="loading"
+      :id="`bar-chart${index}`"
+      style="width: 100%; height: 400px"
+    >
       <el-empty v-if="isError" description="请求失败"></el-empty>
     </div>
   </div>
@@ -52,7 +41,7 @@ export default {
       type: String,
       default: "",
     },
-    inds: {
+    index: {
       type: Number,
       default() {
         return 0;
@@ -62,20 +51,7 @@ export default {
   mixins: [myMixin],
   data() {
     return {
-      chartData: {
-        analysisTypeCode: "示例数据分析",
-        engineCode: "引擎001",
-        engineTypeName: "示例引擎",
-        xaixs: "时间",
-        yaixs: "数值",
-        data: [
-          {
-            xData: ["2024-01-01", "2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05"],
-            yData: [10, 20, 30, 40, 50],
-            title: "数据集1",
-          },
-        ],
-      },
+      chartData: {},
       chartType: "line", // 默认图表类型是折线图
       color1: "#406DAB", // 默认颜色
       loading: false,
@@ -85,8 +61,6 @@ export default {
   mounted() {
     if (this.fileAddr) {
       this.getData();
-    } else {
-      this.drawChart(); // 如果没有文件地址,直接绘制模拟数据
     }
   },
   methods: {
@@ -96,10 +70,10 @@ export default {
         try {
           this.loading = true;
           this.cancelToken = axios.CancelToken.source();
-          // const resultChartsData = await axios.get(this.fileAddr, {
-          //   cancelToken: this.cancelToken.token,
-          // });
-          // this.chartData = resultChartsData.data;
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token,
+          });
+          this.chartData = resultChartsData.data;
           // 使用 nextTick 来确保 DOM 渲染完成后绘制图表
           nextTick(() => {
             this.drawChart();
@@ -115,22 +89,29 @@ export default {
     },
     // 绘制图表
     drawChart() {
-      const chartDataset = this.chartData.data[0];
-      const trace = {
-        x: chartDataset.xData, // 横坐标数据
-        y: chartDataset.yData, // 纵坐标数据
-        type: this.chartType, // 当前图表类型 ('line' 或 'bar')
-        marker: {
-          color: this.color1, // 图表颜色
-        },
-        line: {
-          color: this.color1, // 折线图颜色
-        },
-        name: chartDataset.title || "数据", // 图例名称
-      };
+      const data = [];
+      this.chartData.data.forEach((turbine, index) => {
+        // 判断图表类型,根据类型调整绘制方式
+        const chartConfig = {
+          x: turbine.xData, // X 数据
+          y: turbine.yData, // Y 数据
+          name: turbine.engineName, // 使用机组名称
+          // line: {
+          //   color: this.colors[index % this.colors.length], // 为每个机组分配不同的颜色
+          // },
+        };
+
+        if (this.chartType === "line") {
+          chartConfig.mode = "lines"; // 如果是折线图
+        } else if (this.chartType === "bar") {
+          chartConfig.type = "bar"; // 如果是柱状图
+        }
+
+        data.push(chartConfig);
+      });
 
       const layout = {
-        title: this.chartData.analysisTypeCode || "图表", // 图表标题
+        title: this.chartData.title,
         xaxis: {
           title: this.chartData.xaixs || "X轴", // 横坐标标题
         },
@@ -144,26 +125,24 @@ export default {
           b: 50,
         },
         autosize: true, // 开启自适应
+        barmode: this.chartType === "bar" ? "stack" : "group", // 如果是柱状图则启用堆叠
       };
 
-      // 渲染图表
-      Plotly.newPlot(
-        `bar-chart${this.inds}`,
-        [trace,trace],
-        layout,
-        {
-          responsive: true,
-        }
-      );
+      // 使用 Plotly.react 来更新图表
+      Plotly.react(`bar-chart${this.index}`, data, layout, {
+        responsive: true,
+      });
     },
+
     // 切换图表类型
     toggleChartType() {
-      this.chartType = this.chartType === "line" ? "bar" : "line";
-      this.drawChart();
+      this.chartType = this.chartType === "line" ? "bar" : "line"; // 切换图表类型
+      this.drawChart(); // 重新绘制图表
     },
+
     // 更新图表颜色
     updateChartColor() {
-      this.drawChart();
+      this.drawChart(); // 更新颜色后重新绘制图表
     },
   },
 };

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

@@ -0,0 +1,190 @@
+<!--
+ * @Author: your name
+ * @Date: 2025-01-20 11:41:41
+ * @LastEditTime: 2025-01-20 12:12:42
+ * @LastEditors: bogon
+ * @Description: In User Settings Edit
+ * @FilePath: /performance-test/src/views/performance/components/chartsCom/lineChartsFen.vue
+-->
+<template>
+  <div>
+    <!-- 图表控制面板 分图-->
+    <div style="display: flex; align-items: center">
+      <div style="margin-right: 20px; display: flex; align-items: center">
+        <el-color-picker
+          size="small"
+          v-model="color1"
+          show-alpha
+          @change="updateChartColor"
+        ></el-color-picker>
+        <span style="margin-left: 10px">自定义颜色</span>
+      </div>
+      <div>
+        <el-button size="small" @click="toggleChartType">
+          切换为{{ chartType === "line" ? "柱状图" : "折线图" }}
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 图表容器 -->
+    <div
+      v-loading="loading"
+      :id="`line-chart-fen-${index}`"
+      style="width: 100%; height: 400px"
+    >
+      <el-empty v-if="isError" description="请求失败"></el-empty>
+    </div>
+  </div>
+</template>
+
+<script>
+import { nextTick } from "vue"; // 导入 nextTick
+import Plotly from "plotly.js-dist";
+import axios from "axios";
+import { myMixin } from "@/mixins/chartRequestMixin"; // 假设你需要的 mixin
+
+export default {
+  props: {
+    fileAddr: {
+      type: String,
+      default: "",
+    },
+    index: {
+      type: Number,
+      default() {
+        return 0;
+      },
+    },
+    fieldEngineCode: {
+      type: String,
+      default: "",
+    },
+  },
+  mixins: [myMixin],
+  data() {
+    return {
+      chartData: {},
+      chartType: "line", // 默认图表类型是折线图
+      color1: "#406DAB", // 默认颜色
+      loading: false,
+      isError: false,
+    };
+  },
+  mounted() {
+    if (this.fileAddr) {
+      this.getData();
+    }
+  },
+  methods: {
+    // 获取数据
+    async getData() {
+      if (this.fileAddr !== "") {
+        try {
+          this.loading = true;
+          this.cancelToken = axios.CancelToken.source();
+          const resultChartsData = await axios.get(this.fileAddr, {
+            cancelToken: this.cancelToken.token,
+          });
+          this.chartData = resultChartsData.data;
+          // 使用 nextTick 来确保 DOM 渲染完成后绘制图表
+          nextTick(() => {
+            this.drawChart();
+            this.isError = false;
+            this.loading = false;
+          });
+        } catch (error) {
+          console.error("Error loading data:", error);
+          this.isError = true;
+          this.loading = false;
+        }
+      }
+    },
+    // 绘制图表
+    drawChart() {
+      // 先将数据按照条件进行排序
+      const sortedData = this.chartData.data.sort((a, b) => {
+        // 符合条件的数据排在前面
+        if (
+          a.engineCode === this.fieldEngineCode &&
+          b.engineCode !== this.fieldEngineCode
+        ) {
+          return 1; // a 排在前面
+        }
+        if (
+          a.engineCode !== this.fieldEngineCode &&
+          b.engineCode === this.fieldEngineCode
+        ) {
+          return -1; // b 排在前面
+        }
+        return 0; // 如果两者都符合或都不符合,保持原顺序
+      });
+
+      const data = [];
+      const lineData = []; // 用于存储所有线图数据
+
+      sortedData.forEach((turbine, index) => {
+        // 判断当前机组的 engineCode 是否与 fieldEngineCode 匹配
+        const color =
+          turbine.engineCode === this.fieldEngineCode ? this.color1 : "#D3D3D3"; // #D3D3D3 为灰色
+
+        const chartConfig = {
+          x: turbine.xData, // X 数据
+          y: turbine.yData, // Y 数据
+          name: turbine.engineName, // 使用机组名称
+          line: { color }, // 设置线条颜色
+          marker: { color }, // 设置柱状图的颜色
+        };
+
+        // 判断是否为线图
+        if (this.chartType === "line") {
+          chartConfig.mode = "lines"; // 如果是折线图
+          lineData.push(chartConfig); // 将线图数据存储到 lineData 中
+        } else if (this.chartType === "bar") {
+          chartConfig.type = "bar"; // 如果是柱状图
+          data.push(chartConfig); // 将柱状图数据存储到 data 中
+        }
+      });
+
+      // 将非线图的数据放到前面,线图的数据放到最后
+      const finalData = [...data, ...lineData]; // 先放柱状图,再放线图
+
+      const layout = {
+        title: this.chartData.title || "图表",
+        xaxis: {
+          title: this.chartData.xaixs || "X轴", // 横坐标标题
+        },
+        yaxis: {
+          title: this.chartData.yaixs || "Y轴", // 纵坐标标题
+        },
+        margin: {
+          l: 50,
+          r: 50,
+          t: 50,
+          b: 50,
+        },
+        autosize: true, // 开启自适应
+        barmode: this.chartType === "bar" ? "stack" : "group", // 如果是柱状图则启用堆叠
+      };
+
+      // 使用 Plotly.react 来更新图表
+      Plotly.react(`line-chart-fen-${this.index}`, finalData, layout, {
+        responsive: true,
+      });
+    },
+    // 切换图表类型
+    toggleChartType() {
+      this.chartType = this.chartType === "line" ? "bar" : "line"; // 切换图表类型
+      this.drawChart(); // 重新绘制图表
+    },
+
+    // 更新图表颜色
+    updateChartColor() {
+      this.drawChart(); // 更新颜色后重新绘制图表
+    },
+  },
+};
+</script>
+
+<style scoped>
+/* 样式可以根据需求自定义 */
+</style>