ソースを参照

增加分析报告页面

SunZehao 1 年間 前
コミット
a99d0412e4

+ 4 - 0
src/App.vue

@@ -130,6 +130,10 @@
                     icon: 'Monitor',
                     index: '/generatingCap/dataAnalysis/agcAnalysis',
                     name: 'AGC曲线偏差分析'
+                }, {
+                    icon: 'Files',
+                    index: '/generatingCap/dataAnalysis/analysisReport',
+                    name: '分析报告'
                 }, ],
                 memuCloseTimeout: null,
                 fixed: false,

+ 9 - 0
src/router/index.js

@@ -217,6 +217,15 @@ const routes = [
         component: () =>
         import("../views/generatingCapacity/dataAnalysis/agcAnalysis/index.vue"),
     },
+    {
+        path: "/generatingCap/dataAnalysis/analysisReport",
+        name: "dataAnalysisAnalysisReport",
+        meta: {
+        title: "分析报告",
+        },
+        component: () =>
+        import("../views/generatingCapacity/report/index.vue"),
+    },
 ]
 
 const router = createRouter({

+ 74 - 0
src/views/generatingCapacity/report/fixGetPDF.js

@@ -0,0 +1,74 @@
+/*
+ * @Author: 蒋珅 11455645+jiang-shena@user.noreply.gitee.com
+ * @Date: 2023-06-12 18:13:48
+ * @LastEditors: 蒋珅 11455645+jiang-shena@user.noreply.gitee.com
+ * @LastEditTime: 2023-06-13 16:26:14
+ * @FilePath: \PowerAnalysis\src\pages\report\fixGetPDF.js
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+// 页面导出为pdf格式
+import html2Canvas from 'html2canvas';
+import jsPDF from 'jspdf';
+
+const htmlToPdf = {
+  getPdf( loading,title,) {
+    // loading = true;
+    console.log(loading);
+    html2Canvas(document.querySelector('#pdfDom'), {
+      allowTaint: false,
+      taintTest: false,
+      logging: false,
+      useCORS: true,
+      dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍
+      scale: 4, //按比例增加分辨率
+    }).then((canvas) => {
+      var pdf = new jsPDF('p', 'mm', 'a4'); //A4纸,纵向
+      var ctx = canvas.getContext('2d'),
+        a4w = 190,
+        a4h = 272, //A4大小,210mm x 297mm,四边各保留10mm的边距,显示区域190x277
+        imgHeight = Math.floor((a4h * canvas.width) / a4w), //按A4显示比例换算一页图像的像素高度
+        renderedHeight = 0;
+
+      while (renderedHeight < canvas.height) {
+        var page = document.createElement('canvas');
+        page.width = canvas.width;
+        page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页
+
+        //用getImageData剪裁指定区域,并画到前面创建的canvas对象中
+        page
+          .getContext('2d')
+          .putImageData(
+            ctx.getImageData(
+              0,
+              renderedHeight,
+              canvas.width,
+              Math.min(imgHeight, canvas.height - renderedHeight),
+            ),
+            0,
+            0,
+          );
+        pdf.addImage(
+          page.toDataURL('image/jpeg', 1.0),
+          'JPEG',
+          10,
+          10,
+          a4w,
+          Math.min(a4h, (a4w * page.height) / page.width),
+        ); //添加图像到页面,保留10mm边距
+
+        renderedHeight += imgHeight;
+        if (renderedHeight < canvas.height) {
+          pdf.addPage(); //如果后面还有内容,添加一个空页
+        }
+        // delete page;
+      }
+      //保存文件
+      pdf.save('发电能力分析' + '.pdf');
+      // loading = false;
+      console.log(loading);
+    });
+  },
+};
+
+export default htmlToPdf;
+

+ 374 - 0
src/views/generatingCapacity/report/index.vue

@@ -0,0 +1,374 @@
+<template>
+    <div class="analysisReport" :class="!theme ? 'themeDark' : 'themeLight'">
+        <div class="analysisReportMain">
+            <p>分析报告</p>
+            <div class="seach">
+                <el-form class="" :inline="true">
+                    <el-form-item label="场站" class="!mb-0">
+                        <el-select v-model="station" clearable class="w-[150px]">
+                            <el-option v-for="item in stationList" :key="item.id" :label="item.name" :value="item.id">
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="开始" class="!mb-0 ml-2">
+                        <el-date-picker v-model="val1" @change="BeginChange(val1)" type="month" value-format="YYYY-MM"
+                            placeholder="选择日期">
+                        </el-date-picker>
+                    </el-form-item>
+                    <el-form-item label="结束" class="!mb-0">
+                        <el-date-picker v-model="value2" @change="EndChange(value2)" type="month" value-format="YYYY-MM"
+                            placeholder="选择日期">
+                        </el-date-picker>
+                    </el-form-item>
+                    <el-form-item class="!mb-0">
+                        <el-button type="primary" @click="addform">查询</el-button>
+                    </el-form-item>
+                </el-form>
+            </div>
+            <div class="main warn-table" :style="{ height: tableHeight}">
+                <el-table :data="tableData" size="large">
+                    <el-table-column resizable align="center" type="index" label="序号" width="100" />
+                    <el-table-column resizable align="center" prop="station" label="场站名称" />
+                    <el-table-column resizable align="center" prop="time" label="时间" />
+                    <el-table-column resizable align="center" prop="wtidcount" label="风机数量" />
+                    <el-table-column resizable align="center" label="操作">
+                        <template #default="scope">
+                            <!-- <el-button size="small" @click="handleEdit(scope.$index, scope.row)"
+                    >下载</el-button
+                > -->
+                            <el-button size="small" type="danger" @click="handleReport(scope.$index, scope.row)">查看报告
+                            </el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+            </div>
+        </div>
+    </div>
+    <el-dialog v-model="centerDialogVisible" title="风电场性能分析报告" width="50%" center :before-close="handleClose"
+        style="padding: 15px 40px;">
+        <div id="pdfDom">
+            <!-- <h3 style="font-weight: bolder; font-size: 18px; color: black;text-aling:center">风电场性能分析报告</h3> -->
+            <p>
+                <span class="ml-5" style="width: 500px;">场站: {{ nbdata.name }}</span>
+                <span class="ml-77">风机型号: {{ nbdata.model }}</span>
+            </p>
+            <p>
+                <span class="ml-5">风机数量: {{ nbdata.quantity }}</span>
+                <span class="ml-87">装机容量(MW): {{ nbdata.capacity }}</span>
+            </p>
+            <p>
+                <span class="ml-5">报告生成日期: {{ time }}</span>
+                <span class="ml-70">数据分析周期: {{ eltime }}</span>
+            </p>
+            <h3 style="font-weight: bolder; font-size: 18px; color: black">概述:</h3>
+            <p class="ml-7">
+                报告基于曲线偏差率、静态偏差对风、容量系数、停机时长、分别对场站{{ nbdata.quantity }}台风机进行了性能分析,其中有{{wtcount}}台风机指标严重异常,信息如下:
+            </p>
+            <h3 style="font-weight: bolder; font-size: 18px; color: black">
+                1、曲线偏差率
+            </h3>
+            <p class="ml-7">
+                曲线偏差率对不同风速区间的实际功率和保证功率做偏差率分析,高偏差率表明存在需要进一步调查潜在问题,偏差率负值表明实际功率低于保证功率
+            </p>
+
+            <el-table :data="curve" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 20px">
+                <el-table-column prop="section" align="center" label="风速区间" width="180" />
+                <el-table-column prop="module" align="center" label="偏差率" />
+                <el-table-column prop="wtidcount" align="center" label="风机数量" />
+                <el-table-column prop="windturbine" align="center" label="风机编号" />
+            </el-table>
+            <h3 style="font-weight: bolder; font-size: 18px; color: black">
+                2、静态偏航对风
+            </h3>
+            <p class="ml-7">
+                静态偏航对风指风机的叶片与风向之间的偏差,偏差角度过大表明对风存在问题,以下为5-10m风速区间的对风误差
+            </p>
+            <el-table :data="staticwind" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 20px">
+                <el-table-column prop="section" align="center" label="严重程度" width="180" />
+                <el-table-column prop="wtidcount" align="center" label="风机数量" />
+                <!-- <el-table-column prop="amount1" label="风机数量" /> -->
+                <el-table-column prop="windturbine" align="center" label="风机编号" />
+            </el-table>
+            <h3 style="font-weight: bolder; font-size: 18px; color: black">
+                3、容量系数
+            </h3>
+            <p class="ml-7">
+                容量系数是风机发电量能力的指标,数值越低,说明发电效率越低
+            </p>
+            <el-table :data="mrlxs" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 20px">
+                <el-table-column prop="section" align="center" label="容量系数" width="180" />
+                <!-- <el-table-column prop="name" label="偏差率" /> -->
+                <el-table-column prop="wtidcount" align="center" label="风机数量" />
+                <el-table-column prop="windturbine" align="center" label="风机编号" />
+            </el-table>
+            <h3 style="font-weight: bolder; font-size: 18px; color: black">
+                4、桨距角
+            </h3>
+            <p class="ml-7">
+                桨距角分析并网开桨和停机收桨,并网状态下桨距角趋近于0度最优,停机状态下桨距角趋近于90度最优
+            </p>
+            <el-table :data="blade" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 20px">
+                <el-table-column prop="section" align="center" label="桨距角" width="180" />
+                <!-- <el-table-column prop="name" label="偏差率" /> -->
+                <el-table-column prop="wtidcount" align="center" label="风机数量" />
+                <el-table-column prop="windturbine" align="center" label="风机编号" />
+            </el-table>
+            <h3 style="font-weight: bolder; font-size: 18px; color: black">
+                5、停机时间
+            </h3>
+            <p class="ml-7">
+                小风速下停机时间越长反应出低风速风机切入不及时,暴风天气不停机反应出风机切出不及时
+            </p>
+            <el-table :data="stoptime" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 20px">
+                <el-table-column prop="section" align="center" label="风速区间" width="180" />
+
+                <el-table-column prop="wtidcount" align="center" label="风机数量" />
+                <el-table-column prop="remark" align="center" label="累计时间(min)" />
+                <el-table-column prop="windturbine" align="center" label="风机编号" />
+            </el-table>
+            <!-- <h3 style="font-weight: bolder; font-size: 18px; color: black">
+    5、损失电量
+</h3>
+<p class="ml-7">
+    损失电量指因故障或维护等原因导致风机未能正常发电,损失电量占比越高,存在的问题越明显
+</p>
+<el-table
+    :data="tableData1"
+    :span-method="objectSpanMethod"
+    border
+    style="width: 100%; margin-top: 20px"
+>
+    <el-table-column prop="id" align="center" label="损失占比" width="180" />
+
+    <el-table-column prop="amount1" align="center" label="风机数量" />
+    <el-table-column prop="amount2" align="center" label="风机编号" />
+</el-table> -->
+            <h3 style="font-weight: bolder; font-size: 18px; color: black">
+                结论及建议
+            </h3>
+            <p class="ml-7">
+                综上统计周期内数据分析,{{ nbdata.name }}的{{hjwtid}}台风机出现频率最高为{{hjcount}}次,可做为重点检修对象,详细可参考分析系统分析功能。
+            </p>
+        </div>
+        <template #footer>
+            <span class="dialog-footer">
+                <el-button @click="handleClose">取消</el-button>
+                <!-- <el-button type="primary" @click="centerDialogVisible = false">
+        确定
+    </el-button> -->
+                <el-button @click="exportPDF" type="primary" :loading="loading">导出 PDF</el-button>
+            </span>
+        </template>
+    </el-dialog>
+</template>
+
+<script setup name="report">
+    import httpRequest from '@/utils/request.js'
+    import jsPDF from 'jspdf';
+    import html2canvas from 'html2canvas';
+    import htmlToPdf from "./fixGetPDF";
+    import {
+        ref,
+        onMounted,
+        reactive,
+        watch
+    } from "vue";
+    import {
+        useStore
+    } from 'vuex';
+
+    const curve = ref([]);
+    const mrlxs = ref([]);
+    const blade = ref([]);
+
+    const staticwind = ref([]);
+    const stoptime = ref([]);
+    const nbdata = ref({});
+    const loading = ref(false)
+    const tableHeight = ref(window.innerHeight - 210 + 'px')
+
+    const exportPDF = () => {
+        loading.value = true;
+        // 调用htmlToPdf工具函数
+        htmlToPdf.getPdf(
+            document.querySelector("#pdfDom"),
+            "风电场性能分析报告"
+        );
+        // 定时器模拟按钮loading动画的时间
+        setTimeout(() => {
+            loading.value = false;
+            ElMessage.success('打印成功!');
+        }, 1000);
+        centerDialogVisible.value = false
+    }
+
+
+    const centerDialogVisible = ref(false);
+    /**场站 */
+    const stationList = ref([]);
+    const funGetStation = async () => {
+        const res = await request.get("/base/station");
+        stationList.value = res.data;
+    };
+    /**查询表格数据 */
+    const tableData = ref();
+    const station = ref("");
+    const addform = async () => {
+        const res = await request.get(
+            `/report/list?station=${station.value}&st=${val1.value}&et=${value2.value}`
+        );
+
+        //    res.data.forEach((ele)=>{
+        //        ele.time=ele.time.slice(0, 7);
+        //    })
+        tableData.value = res.data;
+    };
+
+    let val1 = ref();
+    let value2 = ref();
+    const BeginChange = (val) => {
+        // console.log(val);
+        val1.value = val;
+        // console.log(val);
+    };
+    const EndChange = (val) => {
+        // console.log(val);
+        value2.value = val;
+    };
+    let time = ref();
+    let eltime = ref();
+    let wtcount = ref()
+    let hjwtid = ref()
+    let hjcount = ref()
+    const handleReport = async (index, row) => {
+        time.value = row.time;
+        //   console.log(index, row)
+        centerDialogVisible.value = true;
+        const res = await request.get(
+            `/report/info?station=${row.station}&date=${row.time}`
+        );
+        nbdata.value = res.data.station;
+        //    console.log('nb',nbdata.value);
+        if (res.data.info.curve.length) {
+            res.data.info.curve.forEach((ele) => {
+                ele.module = "偏差率负值";
+            });
+        }
+
+        curve.value = res.data.info.curve;
+        mrlxs.value = res.data.info.mrlxs;
+        blade.value = res.data.info.blade;
+        staticwind.value = res.data.info.staticwind;
+        stoptime.value = res.data.info.stoptime;
+        eltime.value = res.data.time;
+        wtcount.value = res.data.wtcount;
+        hjwtid.value = res.data.hjwtid;
+        hjcount.value = res.data.hjcount;
+    };
+
+    const getTime1 = (val) => {
+        //时间戳处理,val=1是默认开始时间(当前月第一天),val=2是默认结束时间(今天)
+        var date = new Date();
+        var year = date.getFullYear(),
+            month = date.getMonth() + 1,
+            day = date.getDate();
+        month >= 1 && month <= 9 ? (month = "0" + month) : "";
+        day >= 0 && day <= 9 ? (day = "0" + day) : "";
+        var begin = year + "-" + '05';
+        var end = year + "-" + month;
+        if (val == 1) {
+            return begin;
+        } else if (val == 2) {
+            return end;
+        }
+    };
+
+    const handleClose = (() => {
+        reset();
+        centerDialogVisible.value = false;
+    })
+
+    const reset = (() => {
+        curve.value = [];
+        mrlxs.value = [];
+        blade.value = [];
+        staticwind.value = [];
+        stoptime.value = [];
+        eltime.value = '';
+        wtcount.value = '';
+        hjwtid.value = '';
+        hjcount.value = '';
+    });
+
+
+    const theme = ref(null)
+    const store = useStore()
+    watch(() => store.state.theme, (newVal, oldVal) => {
+        theme.value = newVal
+        funGetStation()
+        addform()
+    }, {
+        deep: true
+    })
+
+    onMounted(() => {
+        funGetStation();
+        theme.value = store.state.theme
+        val1.value = getTime1(1);
+        value2.value = getTime1(2);
+        tableHeight.value = window.innerHeight - 210 + 'px'
+        addform()
+    });
+</script>
+<style lang="less" scoped>
+    .analysisReport {
+        padding: 20px;
+
+        p {
+            font-size: 16px;
+            margin-left: 20px;
+        }
+
+        .seach {
+            padding: 20px 0 0 20px;
+        }
+
+        .main {
+            width: calc(100% - 20px);
+            padding: 10px;
+            border-radius: 10px;
+        }
+    }
+
+    .themeDark {
+
+        p {
+            color: #fff;
+        }
+
+        .main {
+            background: #161f1e;
+        }
+
+    }
+
+    .themeLight {
+        padding: 0;
+
+        p {
+            color: #000;
+        }
+
+        .main {
+            background: #edeffb;
+        }
+
+        .analysisReportMain {
+            padding: 20px 0;
+            border-radius: 10px;
+            background: #fff;
+
+        }
+
+    }
+</style>

+ 9 - 2
src/views/intelligentReporting/reporting/index.vue

@@ -33,13 +33,15 @@
                         </el-table-column>
                         <el-table-column align="right">
                             <template #default="scope">
-                                <el-button type="primary" @click="handleRun(scope.$index)">运行</el-button>
+                                <el-button type="primary" :disabled="btnloading" @click="handleRun(scope.$index)">运行
+                                </el-button>
                                 <el-button type="danger" @click="handleDelete(scope.$index)">删除
                                 </el-button>
                             </template>
                         </el-table-column>
                     </el-table>
-                    <el-button class="run-all-script" type="primary" @click="runAllScript">运行所有脚本</el-button>
+                    <el-button class="run-all-script" type="primary" :disabled="btnloading" @click="runAllScript">运行所有脚本
+                    </el-button>
                 </div>
 
                 <div class="listBot warn-table">
@@ -88,6 +90,7 @@
                 theme: null,
                 tableHeight: document.documentElement.clientHeight - 115,
                 listHeight: (document.documentElement.clientHeight - 160) / 2,
+                btnloading: false
             }
         },
         watch: {
@@ -119,13 +122,17 @@
                 this.tableData4.push(this.childCurrentRow)
             },
             runAllScript() {
+                this.btnloading = true
                 run(this.tableData).then(res => {
                     console.log(res)
+                    this.btnloading = false
                 });
             },
             handleRun(index) {
+                this.btnloading = true
                 run(new Array(this.tableData[index])).then(res => {
                     console.log(res)
+                    this.btnloading = false
                 })
             },
             handleDelete(index) {