|
@@ -0,0 +1,982 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="TemperatureMatrix">
|
|
|
|
+ <div class="body" @contextmenu="contextmenu">
|
|
|
|
+ <div class="title">
|
|
|
|
+ <div
|
|
|
|
+ :class="current === item.id ? 'title-onItem' : 'title-item'"
|
|
|
|
+ v-for="(item, index) in stationList"
|
|
|
|
+ :key="index"
|
|
|
|
+ @click="handleChange(item.id, item.name)"
|
|
|
|
+ >
|
|
|
|
+ {{ item.name }}
|
|
|
|
+ </div>
|
|
|
|
+ <div class="select">
|
|
|
|
+ <el-checkbox
|
|
|
|
+ style="margin-right: 20px"
|
|
|
|
+ :indeterminate="isIndeterminate"
|
|
|
|
+ v-model="checkAll"
|
|
|
|
+ @change="handleCheckChange"
|
|
|
|
+ >全选
|
|
|
|
+ </el-checkbox>
|
|
|
|
+ <el-checkbox-group
|
|
|
|
+ v-model="checkedCities"
|
|
|
|
+ @change="handleCheckedCitiesChange"
|
|
|
|
+ >
|
|
|
|
+ <el-checkbox v-for="item in checkboxs" :label="item" :key="item"
|
|
|
|
+ >{{ item }}
|
|
|
|
+ </el-checkbox>
|
|
|
|
+ </el-checkbox-group>
|
|
|
|
+ <div class="bpickers">
|
|
|
|
+ <!-- <div class="search"> -->
|
|
|
|
+ <div class="date">日期:</div>
|
|
|
|
+ <el-date-picker
|
|
|
|
+ class="pickers"
|
|
|
|
+ @change="changes"
|
|
|
|
+ v-model="timeValue"
|
|
|
|
+ type="datetimerange"
|
|
|
|
+ range-separator="至"
|
|
|
|
+ start-placeholder="开始日期"
|
|
|
|
+ end-placeholder="结束日期"
|
|
|
|
+ >
|
|
|
|
+ </el-date-picker>
|
|
|
|
+ <!-- </div> -->
|
|
|
|
+ <div style="margin-left: 10px">
|
|
|
|
+ <el-button type="info" size="small" @click="exportExcel()"
|
|
|
|
+ >导出
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="tables">
|
|
|
|
+ <el-table
|
|
|
|
+ id="tableId"
|
|
|
|
+ ref="multipleTable"
|
|
|
|
+ :data="tableData"
|
|
|
|
+ class="table"
|
|
|
|
+ style="width: 100%"
|
|
|
|
+ height="83vh"
|
|
|
|
+ stripe
|
|
|
|
+ :header-cell-style="{
|
|
|
|
+ background: 'rgb(30,30,30)',
|
|
|
|
+ color: 'rgb(220,220,220)',
|
|
|
|
+ padding: '4px',
|
|
|
|
+ fontSize: '14px',
|
|
|
|
+ border: 'solid 0.5px #000000',
|
|
|
|
+ }"
|
|
|
|
+ :cell-style="{
|
|
|
|
+ height: '40px',
|
|
|
|
+ background: 'rgb(30,30,30)',
|
|
|
|
+ color: 'rgb(220,220,220)',
|
|
|
|
+ padding: '3px',
|
|
|
|
+ fontSize: '12px',
|
|
|
|
+ 'border-top': '0px solid #000000',
|
|
|
|
+ 'border-bottom': '1px solid #000000',
|
|
|
|
+ 'border-right': '1px solid #000000',
|
|
|
|
+ }"
|
|
|
|
+ @cell-click="handleCellClick"
|
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
|
+ >
|
|
|
|
+ <el-table-column type="selection" width="50"></el-table-column>
|
|
|
|
+ <el-table-column prop="code" label="风机" width="90" align="center">
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column label="状态" width="60" align="center">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <span>
|
|
|
|
+ {{ windturbineStatus[scope.row?.status]?.name }}
|
|
|
|
+ </span>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column
|
|
|
|
+ prop="windSpeed"
|
|
|
|
+ width="50"
|
|
|
|
+ label="风速"
|
|
|
|
+ align="center"
|
|
|
|
+ >
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column prop="power" width="60" label="功率" align="center">
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column
|
|
|
|
+ prop="rollSpeed"
|
|
|
|
+ width="70"
|
|
|
|
+ label="发电机转速"
|
|
|
|
+ align="center"
|
|
|
|
+ >
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column
|
|
|
|
+ v-for="(item, index) in contentList"
|
|
|
|
+ :key="index"
|
|
|
|
+ :label="item.name"
|
|
|
|
+ align="center"
|
|
|
|
+ >
|
|
|
|
+ <el-table-column
|
|
|
|
+ v-for="(res, index) in item.children"
|
|
|
|
+ :key="index"
|
|
|
|
+ :label="res.name"
|
|
|
|
+ width="61"
|
|
|
|
+ align="center"
|
|
|
|
+ >
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <span
|
|
|
|
+ :id="scope.row.id === tableData.length - 3 ? 'lastTable' : ''"
|
|
|
|
+ :class="
|
|
|
|
+ scope.row[`${res.keyname}Status`] === 'OverLimit'
|
|
|
|
+ ? 'overModle'
|
|
|
|
+ : scope.row[`${res.keyname}Status`] === 'CrossingLimit'
|
|
|
|
+ ? 'crossModle'
|
|
|
|
+ : scope.row[`${res.keyname}Status`] === 'BadPoint'
|
|
|
|
+ ? 'badModle'
|
|
|
|
+ : ''
|
|
|
|
+ "
|
|
|
|
+ >
|
|
|
|
+ {{ scope.row[res.keyname] ? scope.row[res.keyname] : "" }}
|
|
|
|
+ </span>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import api from "api/index";
|
|
|
|
+import BackgroundData from "utils/BackgroundData";
|
|
|
|
+import XLSX from "xlsx-js-style";
|
|
|
|
+import dayjs from "dayjs";
|
|
|
|
+
|
|
|
|
+import dataJson from "./temperatureMatrixNoDiaJson.json";
|
|
|
|
+
|
|
|
|
+// import XLSXStyle from 'xlsx-style';
|
|
|
|
+const cityOptions = ["越限", "超限", "坏点"];
|
|
|
|
+export default {
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ timeValue: [],
|
|
|
|
+ windturbineStatus: [
|
|
|
|
+ {
|
|
|
|
+ type: 0,
|
|
|
|
+ name: "停机",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ type: 1,
|
|
|
|
+ name: "上电",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ type: 2,
|
|
|
|
+ name: "待机",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ type: 3,
|
|
|
|
+ name: "启动",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ type: 4,
|
|
|
|
+ name: "并网",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ type: 5,
|
|
|
|
+ name: "故障",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ type: 6,
|
|
|
|
+ name: "维护",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ type: 7,
|
|
|
|
+ name: "离线",
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ contentList: [],
|
|
|
|
+ hanb: "",
|
|
|
|
+ tableData: [],
|
|
|
|
+ totablejs: [],
|
|
|
|
+ stationList: [],
|
|
|
|
+ current: "",
|
|
|
|
+ intervals: null,
|
|
|
|
+ multipleSelection: [],
|
|
|
|
+ chooseList: [],
|
|
|
|
+ refreshFlag: false,
|
|
|
|
+ statusList: [
|
|
|
|
+ {
|
|
|
|
+ name: "正常",
|
|
|
|
+ lable: "Normal",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ name: "越限",
|
|
|
|
+ lable: "CrossingLimit",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ name: "超限",
|
|
|
|
+ lable: "OverLimit",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ name: "坏点",
|
|
|
|
+ lable: "BadPoint",
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ checkboxs: cityOptions,
|
|
|
|
+ checkedCities: ["越限", "超限", "坏点"],
|
|
|
|
+ checkAll: true,
|
|
|
|
+ isIndeterminate: true,
|
|
|
|
+ controlErorCodes: [
|
|
|
|
+ "控制成功",
|
|
|
|
+ "控制命令发送失败",
|
|
|
|
+ "无效的控制地址",
|
|
|
|
+ "被控设备异常",
|
|
|
|
+ "无效的控制功能",
|
|
|
|
+ "网络连接错误,检查场站通信",
|
|
|
|
+ "控制结果读取超时",
|
|
|
|
+ "未知错误",
|
|
|
|
+ "控制命令错误",
|
|
|
|
+ "收到无法识别数据",
|
|
|
|
+ "未读取到数据包",
|
|
|
|
+ "未知错误",
|
|
|
|
+ "风机操作过频繁",
|
|
|
|
+ "风机被挂牌",
|
|
|
|
+ "风机操作与风机状态不符",
|
|
|
|
+ "需要登录",
|
|
|
|
+ ],
|
|
|
|
+ pagenum: 1,
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ mounted() {
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.contentList = dataJson.column;
|
|
|
|
+ this.tableData = dataJson.data;
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ cheshi() {
|
|
|
|
+ const lastTable = document.getElementById("lastTable").getClientRects();
|
|
|
|
+ const tableId = document.getElementById("tableId").getClientRects();
|
|
|
|
+ if (lastTable[0].top < tableId[0].bottom) {
|
|
|
|
+ this.pagenum = this.pagenum + 1;
|
|
|
|
+ this.getData();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ handleCheckChange(val) {
|
|
|
|
+ this.tableData = [];
|
|
|
|
+ this.pagenum = 1;
|
|
|
|
+ this.checkedCities = val ? cityOptions : [];
|
|
|
|
+ this.isIndeterminate = false;
|
|
|
|
+ this.multipleSelection = [];
|
|
|
|
+ this.getData();
|
|
|
|
+ },
|
|
|
|
+ handleCheckedCitiesChange(value) {
|
|
|
|
+ let checkedCount = value.length;
|
|
|
|
+ this.checkAll = checkedCount === this.checkboxs.length;
|
|
|
|
+ this.isIndeterminate =
|
|
|
|
+ checkedCount > 0 && checkedCount < this.checkboxs.length;
|
|
|
|
+ this.multipleSelection = [];
|
|
|
|
+ this.tableData = [];
|
|
|
|
+ this.pagenum = 1;
|
|
|
|
+ this.getData();
|
|
|
|
+ },
|
|
|
|
+ opened() {
|
|
|
|
+ let date = new Date();
|
|
|
|
+ this.timeValue[0] =
|
|
|
|
+ new Date(new Date().toLocaleDateString()).getTime() - 86400000;
|
|
|
|
+ this.timeValue[1] = new Date(new Date().toLocaleDateString()).getTime();
|
|
|
|
+
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ let tableDom = this.$refs.multipleTable?.$refs?.bodyWrapper;
|
|
|
|
+ let time = null;
|
|
|
|
+ tableDom.addEventListener("scroll", () => {
|
|
|
|
+ if (time !== null) {
|
|
|
|
+ clearTimeout(time);
|
|
|
|
+ }
|
|
|
|
+ time = setTimeout(() => {
|
|
|
|
+ this.cheshi();
|
|
|
|
+ }, 100);
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ let stationList = [];
|
|
|
|
+ console.log("61", stationList);
|
|
|
|
+ let stations = this.$store.state.stationList;
|
|
|
|
+ stations.forEach((item) => {
|
|
|
|
+ if (item.id.indexOf("FDC") != -1) {
|
|
|
|
+ stationList.push(item);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ this.stationList = stationList;
|
|
|
|
+ this.current = stationList[0].id;
|
|
|
|
+ this.coordinates = [];
|
|
|
|
+ this.getData();
|
|
|
|
+ this.intervals = setInterval(this.handleData, 60000);
|
|
|
|
+ },
|
|
|
|
+ closed() {
|
|
|
|
+ clearInterval(this.intervals);
|
|
|
|
+ this.intervals = null;
|
|
|
|
+ },
|
|
|
|
+ handleChange(val, nb) {
|
|
|
|
+ this.current = val;
|
|
|
|
+ this.hanb = nb;
|
|
|
|
+ this.tableData = [];
|
|
|
|
+ this.pagenum = 1;
|
|
|
|
+ this.getData();
|
|
|
|
+ },
|
|
|
|
+ handleCellClick(val) {
|
|
|
|
+ this.$refs.multipleTable.toggleRowSelection(val);
|
|
|
|
+ },
|
|
|
|
+ handleSelectionChange(val) {
|
|
|
|
+ this.multipleSelection = val;
|
|
|
|
+ },
|
|
|
|
+ handleData() {
|
|
|
|
+ this.tableData = [];
|
|
|
|
+ this.pagenum = 1;
|
|
|
|
+ this.getData();
|
|
|
|
+ },
|
|
|
|
+ getData() {
|
|
|
|
+ let selectStatus = "";
|
|
|
|
+ let statusArr = [];
|
|
|
|
+ if (this.checkedCities.length < 3) {
|
|
|
|
+ this.checkedCities.forEach((item) => {
|
|
|
|
+ let status = this.statusList.filter((val) => val.name === item)[0];
|
|
|
|
+ if (status.lable) {
|
|
|
|
+ statusArr.push(status.lable);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ selectStatus = statusArr.join(",");
|
|
|
|
+ api
|
|
|
|
+ .temperatureInfo({
|
|
|
|
+ id:
|
|
|
|
+ this.current === "all"
|
|
|
|
+ ? ""
|
|
|
|
+ : this.stationList.filter((item) => item.id === this.current)[0]
|
|
|
|
+ .id,
|
|
|
|
+ status: selectStatus,
|
|
|
|
+ pagenum: this.pagenum,
|
|
|
|
+ pagesize: 200,
|
|
|
|
+ })
|
|
|
|
+ .then((res) => {
|
|
|
|
+ if (res.data.length) {
|
|
|
|
+ let contentList = [];
|
|
|
|
+ let tableDatas = [];
|
|
|
|
+ // console.log(contentList);
|
|
|
|
+ // console.log(tableDatas);
|
|
|
|
+ res.data.forEach((item, index) => {
|
|
|
|
+ let tableData = {};
|
|
|
|
+ tableData.code = item.code;
|
|
|
|
+ tableData.windturbineId = item.windturbineId;
|
|
|
|
+
|
|
|
|
+ tableData.windSpeed = item.windSpeed.toFixed(1);
|
|
|
|
+ tableData.status = Number(item.status);
|
|
|
|
+ tableData.stationId = item.stationId;
|
|
|
|
+ tableData.rollSpeed = item.rollSpeed.toFixed(1);
|
|
|
|
+ tableData.power = item.power.toFixed(1);
|
|
|
|
+ item.temperatureComponentInfos.forEach((val) => {
|
|
|
|
+ if (index === 0) {
|
|
|
|
+ let obj = {
|
|
|
|
+ children: [],
|
|
|
|
+ };
|
|
|
|
+ obj.name = val.name;
|
|
|
|
+ val.temperatureItemInfos.forEach((temp) => {
|
|
|
|
+ if (index === 0) {
|
|
|
|
+ let str = {};
|
|
|
|
+ str.name = temp.name;
|
|
|
|
+ str.keyname = `${val.name}${temp.name}`;
|
|
|
|
+ obj.children.push(str);
|
|
|
|
+ }
|
|
|
|
+ tableData[`${val.name}${temp.name}`] =
|
|
|
|
+ temp.value.toFixed(1);
|
|
|
|
+ tableData[`${val.name}${temp.name}Status`] = temp.status;
|
|
|
|
+ });
|
|
|
|
+ contentList.push(obj);
|
|
|
|
+ } else {
|
|
|
|
+ val.temperatureItemInfos.forEach((temp) => {
|
|
|
|
+ tableData[`${val.name}${temp.name}`] =
|
|
|
|
+ temp.value.toFixed(1);
|
|
|
|
+ tableData[`${val.name}${temp.name}Status`] = temp.status;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ tableDatas.push(tableData);
|
|
|
|
+ // console.log('ha',tableData);
|
|
|
|
+ });
|
|
|
|
+ this.contentList = contentList;
|
|
|
|
+ let arr = [];
|
|
|
|
+ this.contentList.forEach((item) => {
|
|
|
|
+ item.children.forEach((val) => {
|
|
|
|
+ arr.push(val.name);
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ if (tableDatas.length) {
|
|
|
|
+ this.tableData = [...this.tableData, ...tableDatas];
|
|
|
|
+
|
|
|
|
+ this.tableData.forEach((item, index) => {
|
|
|
|
+ item.id = index;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.multipleSelection.forEach((item) => {
|
|
|
|
+ if (item) {
|
|
|
|
+ let tables = this.tableData.filter(
|
|
|
|
+ (val) => val.code === item.code
|
|
|
|
+ )[0];
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.$refs.multipleTable.toggleRowSelection(tables, true);
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ async exportExcel() {
|
|
|
|
+ let fjcode = [];
|
|
|
|
+ // console.log('sb',this.tableData);
|
|
|
|
+ this.tableData.forEach((ele) => {
|
|
|
|
+ fjcode.push(ele.windturbineId);
|
|
|
|
+ });
|
|
|
|
+ let str = fjcode.join(",");
|
|
|
|
+ await api
|
|
|
|
+ .getnb({
|
|
|
|
+ windturbineIds: str,
|
|
|
|
+ startTs: dayjs(this.timeValue[0]).valueOf(),
|
|
|
|
+ endTs: dayjs(this.timeValue[1]).valueOf(),
|
|
|
|
+ })
|
|
|
|
+ .then((res) => {
|
|
|
|
+ // if (res.data.length) {
|
|
|
|
+ let contentList = [];
|
|
|
|
+ let tableDatas = [];
|
|
|
|
+ res.data.forEach((item, index) => {
|
|
|
|
+ let tablejs = {};
|
|
|
|
+ tablejs.code = item.code;
|
|
|
|
+ tablejs.windturbineId = item.windturbineId;
|
|
|
|
+ tablejs.windSpeed = item.windSpeed.toFixed(1);
|
|
|
|
+ tablejs.status = Number(item.status);
|
|
|
|
+ tablejs.stationId = item.stationId;
|
|
|
|
+ tablejs.rollSpeed = item.rollSpeed.toFixed(1);
|
|
|
|
+ tablejs.power = item.power.toFixed(1);
|
|
|
|
+ item.temperatureComponentInfos.forEach((val) => {
|
|
|
|
+ if (index === 0) {
|
|
|
|
+ let obj = {
|
|
|
|
+ children: [],
|
|
|
|
+ };
|
|
|
|
+ obj.name = val.name;
|
|
|
|
+ val.temperatureItemInfos.forEach((temp) => {
|
|
|
|
+ if (index === 0) {
|
|
|
|
+ let str = {};
|
|
|
|
+ str.name = temp.name;
|
|
|
|
+ str.keyname = `${val.name}${temp.name}`;
|
|
|
|
+ obj.children.push(str);
|
|
|
|
+ }
|
|
|
|
+ tablejs[`${val.name}${temp.name}`] = temp.value.toFixed(1);
|
|
|
|
+ tablejs[`${val.name}${temp.name}Status`] = temp.status;
|
|
|
|
+ });
|
|
|
|
+ contentList.push(obj);
|
|
|
|
+ } else {
|
|
|
|
+ val.temperatureItemInfos.forEach((temp) => {
|
|
|
|
+ tablejs[`${val.name}${temp.name}`] = temp.value.toFixed(1);
|
|
|
|
+ tablejs[`${val.name}${temp.name}Status`] = temp.status;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ tableDatas.push(tablejs);
|
|
|
|
+ this.totablejs.push(tablejs);
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ const headers = [
|
|
|
|
+ "时间",
|
|
|
|
+ "机组编号",
|
|
|
|
+ "状态",
|
|
|
|
+ "风速",
|
|
|
|
+ "功率",
|
|
|
|
+ "发电机转速",
|
|
|
|
+ "主轴叶轮侧温度",
|
|
|
|
+ "主轴齿轮箱侧温度",
|
|
|
|
+ "塔底柜温度",
|
|
|
|
+ "机舱柜温度",
|
|
|
|
+ "机舱温度",
|
|
|
|
+ "滑环温度",
|
|
|
|
+ "环境温度",
|
|
|
|
+ "发电机U1绕组温度",
|
|
|
|
+ "发电机U2绕组温度",
|
|
|
|
+ "发电机V1绕组温度",
|
|
|
|
+ "发电机V2绕组温度",
|
|
|
|
+ "发电机W1绕组温度",
|
|
|
|
+ "发电机W2绕组温度",
|
|
|
|
+ "轴a温度",
|
|
|
|
+ "轴b温度",
|
|
|
|
+ "变桨电池柜1温度",
|
|
|
|
+ "变桨电池柜2温度",
|
|
|
|
+ "变桨电池柜3温度",
|
|
|
|
+ "液压压力",
|
|
|
|
+ "液压油温",
|
|
|
|
+ "齿轮箱入口温度",
|
|
|
|
+ "齿轮箱油温",
|
|
|
|
+ "齿轮箱轴1温度",
|
|
|
|
+ "齿轮箱轴2温度",
|
|
|
|
+ ];
|
|
|
|
+ let data = this.totablejs.map((item) => [
|
|
|
|
+ item.code,
|
|
|
|
+ item.windturbineId,
|
|
|
|
+ item.status,
|
|
|
|
+ item.windSpeed,
|
|
|
|
+ item.power,
|
|
|
|
+ item.rollSpeed,
|
|
|
|
+ item.主轴叶轮侧温度,
|
|
|
|
+ item.主轴齿轮箱侧温度,
|
|
|
|
+ item.其他塔底柜温度,
|
|
|
|
+ item.其他机舱柜温度,
|
|
|
|
+ item.其他机舱温度,
|
|
|
|
+ item.其他滑环温度,
|
|
|
|
+ item.其他环境温度,
|
|
|
|
+ item.发电机U1绕组温度,
|
|
|
|
+ item.发电机U2绕组温度,
|
|
|
|
+ item.发电机V1绕组温度,
|
|
|
|
+ item.发电机V2绕组温度,
|
|
|
|
+ item.发电机W1绕组温度,
|
|
|
|
+ item.发电机W2绕组温度,
|
|
|
|
+ item.发电机轴a温度,
|
|
|
|
+ item.发电机轴b温度,
|
|
|
|
+ item.变桨电池柜1温度,
|
|
|
|
+ item.变桨电池柜2温度,
|
|
|
|
+ item.变桨电池柜3温度,
|
|
|
|
+ item.液压压力,
|
|
|
|
+ item.液压油温,
|
|
|
|
+ item.齿轮箱入口油温,
|
|
|
|
+ item.齿轮箱油温,
|
|
|
|
+ item.齿轮箱轴1温度,
|
|
|
|
+ item.齿轮箱轴2温度,
|
|
|
|
+ ]);
|
|
|
|
+ let dataStatus = this.totablejs.map((item) => [
|
|
|
|
+ item.主轴叶轮侧温度Status,
|
|
|
|
+ item.主轴齿轮箱侧温度Status,
|
|
|
|
+ item.其他塔底柜温度Status,
|
|
|
|
+ item.其他机舱柜温度Status,
|
|
|
|
+ item.其他机舱温度Status,
|
|
|
|
+ item.其他滑环温度Status,
|
|
|
|
+ item.其他环境温度Status,
|
|
|
|
+ item.发电机U1绕组温度Status,
|
|
|
|
+ item.发电机U2绕组温度Status,
|
|
|
|
+ item.发电机V1绕组温度Status,
|
|
|
|
+ item.发电机V2绕组温度Status,
|
|
|
|
+ item.发电机W1绕组温度Status,
|
|
|
|
+ item.发电机W2绕组温度Status,
|
|
|
|
+ item.发电机轴a温度Status,
|
|
|
|
+ item.发电机轴b温度Status,
|
|
|
|
+ item.变桨电池柜1温度Status,
|
|
|
|
+ item.变桨电池柜2温度Status,
|
|
|
|
+ item.变桨电池柜3温度Status,
|
|
|
|
+ item.液压压力Status,
|
|
|
|
+ item.液压油温Status,
|
|
|
|
+ item.齿轮箱入口油温Status,
|
|
|
|
+ item.齿轮箱油温Status,
|
|
|
|
+ item.齿轮箱轴1温度Status,
|
|
|
|
+ item.齿轮箱轴2温度Status,
|
|
|
|
+ ]);
|
|
|
|
+
|
|
|
|
+ data.forEach((ele) => {
|
|
|
|
+ if (ele[2] == 0) {
|
|
|
|
+ ele[2] = "停机";
|
|
|
|
+ } else if (ele[2] == 1) {
|
|
|
|
+ ele[2] = "上电";
|
|
|
|
+ } else if (ele[2] == 2) {
|
|
|
|
+ ele[2] = "待机";
|
|
|
|
+ } else if (ele[2] == 3) {
|
|
|
|
+ ele[2] = "启动";
|
|
|
|
+ } else if (ele[2] == 4) {
|
|
|
|
+ ele[2] = "并网";
|
|
|
|
+ } else if (ele[2] == 5) {
|
|
|
|
+ ele[2] = "故障";
|
|
|
|
+ } else if (ele[2] == 6) {
|
|
|
|
+ ele[2] = "维护";
|
|
|
|
+ } else if (ele[2] == 7) {
|
|
|
|
+ ele[2] = "离线";
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ const colors = {
|
|
|
|
+ BadPoint: { fill: { fgColor: { rgb: "C4C4C4" } } },
|
|
|
|
+ OverLimit: { fill: { fgColor: { rgb: "BB3439" } } },
|
|
|
|
+ CrossingLimit: { fill: { fgColor: { rgb: "E0871C" } } },
|
|
|
|
+ Normal: {},
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const worksheet = XLSX.utils.aoa_to_sheet([headers, ...data]);
|
|
|
|
+ const workbook = XLSX.utils.book_new();
|
|
|
|
+
|
|
|
|
+ // 设置单元格的颜色
|
|
|
|
+ for (let row = 0; row < dataStatus.length; row++) {
|
|
|
|
+ let kr = dataStatus[row];
|
|
|
|
+ for (let i = 0; i < kr.length; i++) {
|
|
|
|
+ const status = kr[i];
|
|
|
|
+ let rn = this.getExcelColumn(i + 7) + `${row + 2}`;
|
|
|
|
+ worksheet[rn].s = colors[status]; // 设置颜色
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ worksheet["!cols"] = [{ wpx: 18 * 7.5 }];
|
|
|
|
+
|
|
|
|
+ XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1");
|
|
|
|
+ // XLSX.writeFile(workbook, `${this.hanb}温度矩阵.xlsx`);
|
|
|
|
+ const excelBuffer = XLSX.write(workbook, {
|
|
|
|
+ bookType: "xlsx",
|
|
|
|
+ type: "array",
|
|
|
|
+ });
|
|
|
|
+ this.saveAsExcelFile(excelBuffer, `${this.hanb}温度矩阵`);
|
|
|
|
+ // this.saveAsExcelFile()
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ saveAsExcelFile(buffer, fileName) {
|
|
|
|
+ const data = new Blob([buffer], { type: "application/octet-stream" });
|
|
|
|
+ if (typeof window.navigator.msSaveBlob !== "undefined") {
|
|
|
|
+ // IE10+
|
|
|
|
+ window.navigator.msSaveBlob(data, fileName + ".xlsx");
|
|
|
|
+ } else {
|
|
|
|
+ // Others
|
|
|
|
+ const url = window.URL.createObjectURL(data);
|
|
|
|
+ const link = document.createElement("a");
|
|
|
|
+ link.href = url;
|
|
|
|
+ link.setAttribute("download", fileName + ".xlsx");
|
|
|
|
+ document.body.appendChild(link);
|
|
|
|
+ link.click();
|
|
|
|
+ document.body.removeChild(link);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ /* 右键菜单 */
|
|
|
|
+ contextmenu() {
|
|
|
|
+ const remote = require("electron").remote;
|
|
|
|
+ let that = this;
|
|
|
|
+ let menuTemplate = [];
|
|
|
|
+ menuTemplate = [
|
|
|
|
+ {
|
|
|
|
+ label: "启动",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendCommand({ controlType: "1", deviceType: "Manual" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "停机",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendCommand({ controlType: "2", deviceType: "Manual" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "复位",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendCommand({ controlType: "5", deviceType: "Manual" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "维护",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendCommand({ controlType: "6", deviceType: "Manual" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "取消维护",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendCommand({ controlType: "8", deviceType: "Manual" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "挂牌",
|
|
|
|
+ submenu: [
|
|
|
|
+ {
|
|
|
|
+ label: "检修",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendLock({ value: "CheckLock" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "故障维修",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendLock({ value: "FaultLock" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "场内受累检修",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendLock({ value: "StationCheckLock" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "场内受累故障",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendLock({ value: "StationFaulLock" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "场外受累电网",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendLock({ value: "StationPowerLineLock" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "场外受累天气",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendLock({ value: "StationWeatherLock" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ label: "取消挂牌",
|
|
|
|
+ click() {
|
|
|
|
+ that.sendLock({ value: "UnLock" });
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ ];
|
|
|
|
+ const menu = remote.Menu.buildFromTemplate(menuTemplate);
|
|
|
|
+
|
|
|
|
+ menu.popup(remote.getCurrentWindow());
|
|
|
|
+ },
|
|
|
|
+ sendCommand(msg) {
|
|
|
|
+ let sendList = [];
|
|
|
|
+ let bd = BackgroundData.getInstance();
|
|
|
|
+ if (!bd.LoginUser) {
|
|
|
|
+ this.$notify({
|
|
|
|
+ title: "请登录",
|
|
|
|
+ message: "控制风机需要先登录!",
|
|
|
|
+ type: "warning",
|
|
|
|
+ position: "bottom-right",
|
|
|
|
+ offset: 60,
|
|
|
|
+ duration: 3000,
|
|
|
|
+ });
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ this.multipleSelection.forEach((item) => {
|
|
|
|
+ sendList.push(
|
|
|
|
+ this.$store.state.windturbinelist[item.code.replace("-", "_")]
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (sendList.length > 0) {
|
|
|
|
+ let pairs = {};
|
|
|
|
+ sendList.forEach((item) => {
|
|
|
|
+ let ct = {
|
|
|
|
+ windturbineId: item.windturbineId,
|
|
|
|
+ stationId: item.stationId,
|
|
|
|
+ projectId: item.projectId,
|
|
|
|
+ modelId: item.modelId,
|
|
|
|
+ controlType: Number(msg.controlType),
|
|
|
|
+ lockType: item.lockType,
|
|
|
|
+ userName: `system_${bd.LoginUser.name}`,
|
|
|
|
+ userId: 0,
|
|
|
|
+ auto: false,
|
|
|
|
+ deviceType: msg.deviceType,
|
|
|
|
+ };
|
|
|
|
+ pairs[ct.windturbineId] = ct;
|
|
|
|
+ });
|
|
|
|
+ api.windturbControl(pairs).then((res) => {
|
|
|
|
+ if (res) {
|
|
|
|
+ this.controlSuccess(res);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ sendLock(msg) {
|
|
|
|
+ let bd = BackgroundData.getInstance();
|
|
|
|
+ if (!bd.LoginUser) {
|
|
|
|
+ this.$notify({
|
|
|
|
+ title: "请登录",
|
|
|
|
+ message: "控制风机需要先登录!",
|
|
|
|
+ type: "warning",
|
|
|
|
+ position: "bottom-right",
|
|
|
|
+ offset: 60,
|
|
|
|
+ duration: 3000,
|
|
|
|
+ });
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ let sendList = [];
|
|
|
|
+ this.multipleSelection.forEach((item) => {
|
|
|
|
+ sendList.push(
|
|
|
|
+ this.$store.state.windturbinelist[item.code.replace("-", "_")]
|
|
|
|
+ );
|
|
|
|
+ });
|
|
|
|
+ if (sendList.length > 0) {
|
|
|
|
+ let pairs = {};
|
|
|
|
+ sendList.forEach((item) => {
|
|
|
|
+ let ct = {
|
|
|
|
+ windturbineId: item.windturbineId,
|
|
|
|
+ stationId: item.stationId,
|
|
|
|
+ projectId: item.projectId,
|
|
|
|
+ modelId: item.modelId,
|
|
|
|
+ lockType: msg.value,
|
|
|
|
+ userName: `system_${bd.LoginUser.name}`,
|
|
|
|
+ userId: 0,
|
|
|
|
+ };
|
|
|
|
+ pairs[ct.windturbineId] = ct;
|
|
|
|
+ });
|
|
|
|
+ api.windturbControlLock(pairs).then((res) => {
|
|
|
|
+ if (res) {
|
|
|
|
+ this.controlSuccess(res);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ /* 控制成功 */
|
|
|
|
+ controlSuccess(msg) {
|
|
|
|
+ let bd = BackgroundData.getInstance();
|
|
|
|
+ for (let id in msg.data) {
|
|
|
|
+ let val = msg.data[id];
|
|
|
|
+ if (val.errorCode !== "0") {
|
|
|
|
+ bd.removeCheckouts(val);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ let mss = ""; // 信息
|
|
|
|
+ let iserror = false; // 是否有控制错误的风机
|
|
|
|
+ for (let v in msg.data) {
|
|
|
|
+ let val = msg.data[v];
|
|
|
|
+ if (val.errorCode > 0) {
|
|
|
|
+ iserror = true;
|
|
|
|
+ mss += `${val.windturbineId} ${
|
|
|
|
+ this.controlErorCodes[val.errorCode]
|
|
|
|
+ }\n`;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ let tp = iserror ? "warning" : "success";
|
|
|
|
+ // if (!iserror) {
|
|
|
|
+ // mss = "控制成功";
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ this.$notify({
|
|
|
|
+ title: "控制",
|
|
|
|
+ message: mss,
|
|
|
|
+ type: tp,
|
|
|
|
+ position: "bottom-right",
|
|
|
|
+ offset: 60,
|
|
|
|
+ duration: 3000,
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ /* 控制失败 */
|
|
|
|
+ controlError(err) {
|
|
|
|
+ this.$notify({
|
|
|
|
+ title: "控制出现错误",
|
|
|
|
+ message: err.message,
|
|
|
|
+ type: "warning",
|
|
|
|
+ position: "bottom-right",
|
|
|
|
+ offset: 60,
|
|
|
|
+ duration: 3000,
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ getExcelColumn(n) {
|
|
|
|
+ var ordA = 65;
|
|
|
|
+ var ordZ = 90;
|
|
|
|
+ var len = ordZ - ordA + 1;
|
|
|
|
+ var s = "";
|
|
|
|
+ while (n > 0) {
|
|
|
|
+ var rem = (n - 1) % len;
|
|
|
|
+ s = String.fromCharCode(rem + ordA) + s;
|
|
|
|
+ n = (n - rem - 1) / len;
|
|
|
|
+ }
|
|
|
|
+ return s;
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+</script>
|
|
|
|
+<style lang="less" scoped>
|
|
|
|
+.TemperatureMatrix {
|
|
|
|
+ padding-left: 3%;
|
|
|
|
+ padding-top: 2%;
|
|
|
|
+ .body {
|
|
|
|
+ background-color: #000000;
|
|
|
|
+ height: 89vh;
|
|
|
|
+ width: 102%;
|
|
|
|
+ margin-left: -1%;
|
|
|
|
+ margin-top: -40px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .title {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: row;
|
|
|
|
+ align-items: center;
|
|
|
|
+ margin-left: 1vw;
|
|
|
|
+ padding-top: 8px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 100%;
|
|
|
|
+ background-color: #000000;
|
|
|
|
+ padding-bottom: 10px;
|
|
|
|
+
|
|
|
|
+ .title-item {
|
|
|
|
+ background-color: #242424;
|
|
|
|
+ border-radius: 4px;
|
|
|
|
+ padding: 8px 27px 7px 25px;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ color: #b4bdc0;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .title-onItem {
|
|
|
|
+ background-color: rgba(37, 116, 219, 1);
|
|
|
|
+ border-radius: 4px;
|
|
|
|
+ padding: 8px 27px 7px 25px;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ color: #b4bdc0;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .tables {
|
|
|
|
+ margin-left: 1vw;
|
|
|
|
+ padding-top: 50px;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .el-table {
|
|
|
|
+ position: static;
|
|
|
|
+ background-color: #141414;
|
|
|
|
+ border: 1px solid #000000;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .select {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: row;
|
|
|
|
+ align-items: center;
|
|
|
|
+ margin-left: 30px;
|
|
|
|
+
|
|
|
|
+ .date {
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ color: #ffffff;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .overModle {
|
|
|
|
+ background-color: rgba(186, 50, 55, 1);
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ top: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .crossModle {
|
|
|
|
+ background-color: #e0861a;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ top: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .badModle {
|
|
|
|
+ background-color: #999999;
|
|
|
|
+ position: absolute;
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 100%;
|
|
|
|
+ top: 0;
|
|
|
|
+ left: 0;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .bpickers {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: row;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ margin-left: 20px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|