ln 2 years ago
parent
commit
603ab9f8dd
51 changed files with 5227 additions and 0 deletions
  1. 0 0
      .env
  2. 2 0
      .env.development
  3. 4 0
      .env.eapi
  4. 2 0
      .env.production
  5. 5 0
      babel.config.js
  6. 49 0
      package.json
  7. BIN
      public/favicon.ico
  8. BIN
      public/img/icons/android-chrome-192x192.png
  9. BIN
      public/img/icons/android-chrome-512x512.png
  10. BIN
      public/img/icons/android-chrome-maskable-192x192.png
  11. BIN
      public/img/icons/android-chrome-maskable-512x512.png
  12. BIN
      public/img/icons/apple-touch-icon-120x120.png
  13. BIN
      public/img/icons/apple-touch-icon-152x152.png
  14. BIN
      public/img/icons/apple-touch-icon-180x180.png
  15. BIN
      public/img/icons/apple-touch-icon-60x60.png
  16. BIN
      public/img/icons/apple-touch-icon-76x76.png
  17. BIN
      public/img/icons/apple-touch-icon.png
  18. BIN
      public/img/icons/favicon-16x16.png
  19. BIN
      public/img/icons/favicon-32x32.png
  20. BIN
      public/img/icons/msapplication-icon-144x144.png
  21. BIN
      public/img/icons/mstile-150x150.png
  22. 3 0
      public/img/icons/safari-pinned-tab.svg
  23. 17 0
      public/index.html
  24. 2 0
      public/robots.txt
  25. 51 0
      src/App.vue
  26. 214 0
      src/api/index.js
  27. BIN
      src/assets/img/logo.ico
  28. BIN
      src/assets/img/logo.png
  29. BIN
      src/assets/img/logo2.ico
  30. 116 0
      src/assets/styles/main.css
  31. 86 0
      src/background.js
  32. 161 0
      src/components/echarts/echartsLine.vue
  33. 15 0
      src/main.js
  34. 32 0
      src/registerServiceWorker.js
  35. 51 0
      src/router/index.js
  36. 23 0
      src/store/index.js
  37. 177 0
      src/utils/Blob.js
  38. 274 0
      src/utils/Export2Excel.js
  39. 12 0
      src/utils/exportExcel.js
  40. 56 0
      src/utils/request.js
  41. 28 0
      src/utils/storage.js
  42. 516 0
      src/views/entry/affected.vue
  43. 560 0
      src/views/entry/fault.vue
  44. 512 0
      src/views/entry/maintain.vue
  45. 42 0
      src/views/homePage/detials.vue
  46. 774 0
      src/views/homePage/index.vue
  47. 399 0
      src/views/tablePage/index.vue
  48. 368 0
      src/views/tablePage1/index.vue
  49. 375 0
      src/views/tablePage2/index.vue
  50. 256 0
      src/views/tablePage3/index.vue
  51. 45 0
      vue.config.js

+ 0 - 0
.env


+ 2 - 0
.env.development

@@ -0,0 +1,2 @@
+VUE_APP_API=http://11.0.118.58:8080
+VUE_APP_APIs=http://11.0.118.58:8082

+ 4 - 0
.env.eapi

@@ -0,0 +1,4 @@
+NODE_ENV=eapi
+VUE_APP_API=https://eapi.nxgqt.org
+VUE_APP_IMAGE=https://eapi.nxgqt.org
+VUE_APP_MAP_KEY=df6LUP4BcbGgSGjZLf8sOBSB6a0fktrb

+ 2 - 0
.env.production

@@ -0,0 +1,2 @@
+VUE_APP_API=http://11.0.118.58:8080
+VUE_APP_APIs=http://11.0.118.58:8082

+ 5 - 0
babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+}

+ 49 - 0
package.json

@@ -0,0 +1,49 @@
+{
+  "name": "windpower",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "electron:build": "vue-cli-service electron:build",
+    "electron:serve": "vue-cli-service electron:serve",
+    "postinstall": "electron-builder install-app-deps",
+    "postuninstall": "electron-builder install-app-deps"
+  },
+  "main": "background.js",
+  "dependencies": {
+    "axios": "^0.21.1",
+    "core-js": "^3.6.5",
+    "dayjs": "^1.10.6",
+    "echarts": "^5.1.2",
+    "element-plus": "^1.0.2-beta.55",
+    "element-ui": "^2.15.3",
+    "register-service-worker": "^1.7.1",
+    "script-loader": "^0.7.2",
+    "stompjs": "^2.3.3",
+    "vue": "^3.0.0",
+    "vue-router": "^4.0.0-0",
+    "vuex": "^4.0.0-0",
+    "xlsx": "^0.17.5"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.0",
+    "@vue/cli-plugin-pwa": "~4.5.0",
+    "@vue/cli-plugin-router": "~4.5.0",
+    "@vue/cli-plugin-vuex": "~4.5.0",
+    "@vue/cli-service": "~4.5.0",
+    "@vue/compiler-sfc": "^3.0.0",
+    "electron": "^13.0.0",
+    "electron-devtools-installer": "^3.1.0",
+    "less": "^3.0.4",
+    "less-loader": "^5.0.0",
+    "node-sass": "^4.12.0",
+    "sass-loader": "^8.0.2",
+    "vue-cli-plugin-electron-builder": "~2.1.1"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not dead"
+  ]
+}

BIN
public/favicon.ico


BIN
public/img/icons/android-chrome-192x192.png


BIN
public/img/icons/android-chrome-512x512.png


BIN
public/img/icons/android-chrome-maskable-192x192.png


BIN
public/img/icons/android-chrome-maskable-512x512.png


BIN
public/img/icons/apple-touch-icon-120x120.png


BIN
public/img/icons/apple-touch-icon-152x152.png


BIN
public/img/icons/apple-touch-icon-180x180.png


BIN
public/img/icons/apple-touch-icon-60x60.png


BIN
public/img/icons/apple-touch-icon-76x76.png


BIN
public/img/icons/apple-touch-icon.png


BIN
public/img/icons/favicon-16x16.png


BIN
public/img/icons/favicon-32x32.png


BIN
public/img/icons/msapplication-icon-144x144.png


BIN
public/img/icons/mstile-150x150.png


+ 3 - 0
public/img/icons/safari-pinned-tab.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M8.00251 14.9297L0 1.07422H6.14651L8.00251 4.27503L9.84583 1.07422H16L8.00251 14.9297Z" fill="black"/>
+</svg>

+ 17 - 0
public/index.html

@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title><%= htmlWebpackPlugin.options.title %></title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

+ 2 - 0
public/robots.txt

@@ -0,0 +1,2 @@
+User-agent: *
+Disallow:

+ 51 - 0
src/App.vue

@@ -0,0 +1,51 @@
+<template class="app">
+  
+  <router-view />
+</template>
+<script>
+  
+  export default {
+    components: {
+      
+    },
+    created: function () {
+      
+    },
+    methods: {
+    },
+  }
+</script>
+<style>
+  @import "../src/assets/styles/main.css";
+  body {
+    /* 设置内容不可选中 */
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+  }
+
+  /* .app{
+    background-color: #000000;
+  } */
+  .right {
+    width: 32%;
+    position: absolute;
+    right: 20px;
+    z-index: 99;
+  }
+
+  .statusBar {
+    width: 100%;
+    position: absolute;
+    bottom: 0;
+    left: 0;
+  }
+
+  .titleBar {
+    width: 100%;
+    position: relative;
+    top: 0;
+    left: 0;
+  }
+</style>

+ 214 - 0
src/api/index.js

@@ -0,0 +1,214 @@
+import request from "../utils/request";
+const getwindpowerVal=()=>{
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url:`/windpowerw/getwindpowerVal.action`,
+        method:"get"
+    })
+}
+const getwindpowerLine=()=>{
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url:`/windpowerw/getwindpowerLine.action`,
+        method:"get"
+    })
+}
+const getStation=()=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`/ghost/wplist`,
+        method:"get"
+    })
+}
+const getGroupList=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`/ghost/wtlist?wpid=${data.wpid}`,
+        method:"get"
+    })
+}
+
+const getTableData=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`/ghost/function?wpid=${data.wpid}&beginDate=${data.beginDate}&endDate=${data.endDate}`,
+        method:"get"
+    })
+}
+const getNature=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`/ghost/nature?wpid=${data.wpid}&beginDate=${data.beginDate}&endDate=${data.endDate}`,
+        method:"get"
+    })
+}
+const getShutdownevent=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/shutdownevent?wpid=${data.wpid}&beginDate=${data.beginDate}&endDate=${data.endDate}&type=${data.type}`,
+        method:"get"
+    })
+}
+const natureReal=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`/ghost/natureReal?wpid=${data.wpid}`,
+        method:"get"
+    })
+}
+const freedomList=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/freedomList?wtid=${data.wtid}&beginDate=${data.beginDate}&endDate=${data.endDate}&uniformcodes=${data.uniformcodes}&interval=${data.interval}`,
+        method:"get"
+    })
+}
+const wtls=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`/ghost/wtls`,
+        method:"get"
+    })
+}
+const points=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`/ghost/points`,
+        method:"get"
+    })
+}
+const faultrecord=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/faultrecord?wpid=${data.wpid}&wtid=${data.wtid}&begin=${data.begin}&end=${data.end}&faulttype=${data.faulttype}`,
+        method:"get"
+    })
+}
+const faultrecordAdd=(pairs)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/faultrecord`,
+        method:"post",
+        data:pairs
+    })
+}
+const faultrecordEdit=(pairs)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/faultrecord`,
+        method:"put",
+        data:pairs
+    })
+}
+const faultrecordDel=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/faultrecord/${data.id}`,
+        method:"delete"
+    })
+}
+
+const mainrecord=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/mainrecord?wpid=${data.wpid}&wtid=${data.wtid}&begin=${data.begin}&end=${data.end}`,
+        method:"get"
+    })
+}
+const mainrecordAdd=(pairs)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/mainrecord`,
+        method:"post",
+        data:pairs
+    })
+}
+const mainrecordEdit=(pairs)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/mainrecord`,
+        method:"put",
+        data:pairs
+    })
+}
+const mainrecordDel=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/mainrecord/${data.id}`,
+        method:"delete"
+    })
+}
+
+
+const getLines = (data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/getLines?wpid=${data.wpid}`,
+        method:"get"
+    })
+}
+const getslStatus = (data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/getslStatus`,
+        method:"get"
+    })
+}
+
+const involved = (data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/involved?wpid=${data.wpid}&begin=${data.begin}&end=${data.end}`,
+        method:"get"
+    })
+}
+const involvedAdd=(pairs)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/involved`,
+        method:"post",
+        data:pairs
+    })
+}
+const involvedEdit=(pairs)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/involved`,
+        method:"put",
+        data:pairs
+    })
+}
+const involvedDel=(data)=>{
+    return request({
+        baseURL: process.env.VUE_APP_APIs,
+        url:`ghost/involved/${data.id}`,
+        method:"delete"
+    })
+}
+export default {
+    getwindpowerVal,
+    getwindpowerLine,
+    getStation,
+    getTableData,
+    getNature,
+    getShutdownevent,
+    natureReal,
+    freedomList,
+    wtls,
+    points,
+    faultrecord,
+    faultrecordAdd,
+    faultrecordEdit,
+    faultrecordDel,
+    mainrecord,
+    mainrecordAdd,
+    mainrecordEdit,
+    mainrecordDel,
+    getGroupList,
+    getLines,
+    getslStatus,
+    involved,
+    involvedAdd,
+    involvedEdit,
+    involvedDel,
+};

BIN
src/assets/img/logo.ico


BIN
src/assets/img/logo.png


BIN
src/assets/img/logo2.ico


+ 116 - 0
src/assets/styles/main.css

@@ -0,0 +1,116 @@
+* {
+    margin: 0;
+    padding: 0;
+}
+
+html,
+body,
+#app,
+.wrapper {
+    width: 100%;
+    height: 100%;
+    background-color: #ffffff;
+    overflow: hidden;
+    font-family: "Microsoft YaHei";
+}
+.el-popover{
+    background-color: rgb(36,36,36) !important;
+    border-color: rgb(36,36,36) !important;
+  }
+/*   .el-table{
+    border-color: rgb(36,36,36) !important;
+  }
+  .el-table__border td{
+    border: 1px solid red !important;
+  }
+  .el-table__row>td{
+	border-color: rgb(36,36,36) !important;
+}
+.el-table::before {
+	height: 0px !important;
+}
+.el-table::after {
+	height: 0px !important;
+} */
+.el-dialog{
+  background-color: #ffffff!important;
+}
+.el-form-item__label{
+  color: rgb(220, 220, 220) !important;
+}
+.el-dialog__title{
+  color: #000000 !important;
+}
+.inputs .el-input__inner{
+  /* background-color: #000000 !important; */
+  color: #000000 !important;
+}
+.el-input__inner{
+  /* background-color: rgb(100,100,100) !important; */
+  /* color: rgb(220, 220, 220) !important; */
+  /* border: 1px solid rgba(77, 77, 77, 1) !important; */
+}
+.el-tabs{
+  background-color: black !important;
+  border: none !important;
+  color: rgb(220,220,220) !important;
+}
+.el-table__empty-block{
+  background-color: #ffffff;
+  border: none;
+}
+.el-tabs__item{
+  background-color: #363636 !important;
+  color: rgb(220,220,220) !important;
+  border-color: black !important;
+} 
+.el-tabs__item:hover{
+  background-color: rgb(36,36,36) !important;
+  border-color: black !important;
+}
+.el-tabs__item.is-active{
+  background-color: rgb(29,106,235) !important;
+}
+
+
+.el-table--border:after,.el-table--group:after,.el-table:before {
+  background-color: black;
+  
+  }
+  
+  .el-table--border,.el-table--group {
+    border-color:black;
+  
+  }
+  
+/*   .el-table td,.el-table th {
+    border-bottom:2px solid rgb(36,36,36);
+  } 
+  
+  .el-table--border th,.el-table--border th.gutter:last-of-type {
+    border-bottom:1px solid yellow;
+  
+  }*/
+  
+  .el-table--border td,.el-table--border th {
+    border-right:1px solid rgb(36,36,36);
+  
+  }
+  
+  .el-table__empty-text{
+    color: black;
+  }
+
+  .el-tree-node:focus>.el-tree-node__content {
+    background-color: #000000 !important;
+  }
+
+  .el-tree-node__content:hover {
+    background-color: #000000 !important;
+  }
+  .el-notification .el-icon-success{
+    color: #67C23A !important;
+  }
+  .el-notification .el-icon-warning {
+    color: #E6A23C !important;
+  }

+ 86 - 0
src/background.js

@@ -0,0 +1,86 @@
+'use strict'
+
+import { app, protocol, BrowserWindow } from 'electron'
+import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
+import installExtension, { VUEJS3_DEVTOOLS } from 'electron-devtools-installer'
+const isDevelopment = process.env.NODE_ENV !== 'production'
+
+// Scheme must be registered before the app is ready
+protocol.registerSchemesAsPrivileged([
+  { scheme: 'app', privileges: { secure: true, standard: true } }
+])
+
+async function createWindow() {
+  // Create the browser window.
+  const win = new BrowserWindow({
+    width: 800,
+    height: 600,
+    frame:false,
+    fullscreen:true,
+    webPreferences: {
+      
+      // Use pluginOptions.nodeIntegration, leave this alone
+      // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
+      nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
+      contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
+      nodeIntegration: true,
+      contextIsolation: false,
+      enableRemoteModule: true,   // 打开remote模块
+    }
+  })
+
+  if (process.env.WEBPACK_DEV_SERVER_URL) {
+    // Load the url of the dev server if in development mode
+    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
+    if (!process.env.IS_TEST) win.webContents.openDevTools()
+  } else {
+    createProtocol('app')
+    // Load the index.html when not in development
+    win.loadURL('app://./index.html')
+  }
+}
+
+// Quit when all windows are closed.
+app.on('window-all-closed', () => {
+  // On macOS it is common for applications and their menu bar
+  // to stay active until the user quits explicitly with Cmd + Q
+  if (process.platform !== 'darwin') {
+    app.quit()
+  }
+})
+
+app.on('activate', () => {
+  // On macOS it's common to re-create a window in the app when the
+  // dock icon is clicked and there are no other windows open.
+  if (BrowserWindow.getAllWindows().length === 0) createWindow()
+})
+
+// This method will be called when Electron has finished
+// initialization and is ready to create browser windows.
+// Some APIs can only be used after this event occurs.
+app.on('ready', async () => {
+  if (isDevelopment && !process.env.IS_TEST) {
+    // Install Vue Devtools
+    try {
+      await installExtension(VUEJS3_DEVTOOLS)
+    } catch (e) {
+      console.error('Vue Devtools failed to install:', e.toString())
+    }
+  }
+  createWindow()
+})
+
+// Exit cleanly on request from parent process in development mode.
+if (isDevelopment) {
+  if (process.platform === 'win32') {
+    process.on('message', (data) => {
+      if (data === 'graceful-exit') {
+        app.quit()
+      }
+    })
+  } else {
+    process.on('SIGTERM', () => {
+      app.quit()
+    })
+  }
+}

+ 161 - 0
src/components/echarts/echartsLine.vue

@@ -0,0 +1,161 @@
+<template>
+  <div class="precisionEcharts" :style="style" :id="id"></div>
+</template>
+<script>
+import * as echarts from "echarts";
+import dayjs from "dayjs";
+export default {
+  props: {
+    dataList: {
+      type: Array,
+      required: [],
+    },
+    id: Object,
+    flag: {
+      type: Boolean,
+      default: false,
+    },
+    width: {
+      type: String,
+      default: "600px",
+    },
+    height: {
+      type: String,
+      default: "250px",
+    },
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    style() {
+      return `width: ${this.width}; height: ${this.height};`;
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  updated() {
+    this.$nextTick(() => {
+      this.initChart();
+    });
+  },
+  methods: {
+    initChart() {
+      let xdata = [
+        // '00:00','01:00','02:00','03:00','04:00','05:00','06:00','07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00','20:00','21:00','22:00','23:00','23:30'
+      ];
+      let value1 = [];
+      let value3 = [];
+      let value4 = [];
+      let value9 = [];
+      this.dataList?.forEach((item) => {
+        xdata.push(dayjs(item.time).format("HH:mm"));
+        value1.push(item.value1);
+        value3.push(item.value3);
+        value4.push(item.value4);
+        value9.push(item.value9);
+      });
+      if (xdata.length > 0) {
+        if (this.flag) {
+          xdata.push("24:00");
+          xdata.push("24:00");
+          xdata.push("24:00");
+        } else {
+          xdata.push("24:00");
+          xdata.push("24:00");
+          xdata.push("24:00");
+          xdata.push("24:00");
+          xdata.push("24:00");
+        }
+      }
+
+      let chartDom = document.getElementById(this.id);
+      let myChart = echarts.init(chartDom);
+      let option = {
+        title: {
+          text: "",
+        },
+        legend: {
+          data: ["超短期", "短期当天", "短期次天", "短期三天"],
+          textStyle: {
+            color: "#000000",
+          },
+        },
+        tooltip: {
+          trigger: "axis",
+        },
+        grid: {
+          left: "3%",
+          right: "4%",
+          bottom: "3%",
+          containLabel: true,
+        },
+        xAxis: {
+          type: "category",
+          axisLabel: {
+            interval: this.flag ? 1 : 3,
+            showMinLabel: true,
+            showMaxLabel: false,
+            formatter: "{value}",
+            fontSize: 14,
+            textStyle: {
+              color: "#606769",
+            },
+          },
+          boundaryGap: false,
+          splitLine: { show: false },
+          data: xdata,
+        },
+        yAxis: {
+          type: "value",
+          splitLine: { show: false },
+        },
+        series: [
+          {
+            name: "超短期",
+            type: "line",
+            smooth: true,
+            data: value3,
+          },
+          {
+            name: "短期当天",
+            type: "line",
+            smooth: true,
+            data: value9,
+          },
+          {
+            name: "短期次天",
+            type: "line",
+            smooth: true,
+            data: value1,
+          },
+          {
+            name: "短期三天",
+            type: "line",
+            smooth: true,
+            data: value4,
+          },
+        ],
+      };
+      option && myChart.setOption(option);
+    },
+  },
+  watch: {
+    dataList: {
+      handler(newValue, oldValue) {
+        this.initChart();
+      },
+      deep: true,
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+// .precisionEcharts {
+//   width: 600px;
+//   height: 250px;
+// }
+</style>

+ 15 - 0
src/main.js

@@ -0,0 +1,15 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import './registerServiceWorker'
+import router from './router'
+import store from './store'
+import * as echarts from 'echarts';
+import ElementPlus from 'element-plus';
+import 'element-plus/lib/theme-chalk/index.css';
+import locale from 'element-ui/lib/locale/lang/zh-CN'
+const app = createApp(App)
+app.config.globalProperties.$echarts = echarts
+app.use(store)
+app.use(router)
+app.use(ElementPlus, { locale })
+app.mount('#app')

+ 32 - 0
src/registerServiceWorker.js

@@ -0,0 +1,32 @@
+/* eslint-disable no-console */
+
+import { register } from 'register-service-worker'
+
+if (process.env.NODE_ENV === 'production') {
+  register(`${process.env.BASE_URL}service-worker.js`, {
+    ready () {
+      console.log(
+        'App is being served from cache by a service worker.\n' +
+        'For more details, visit https://goo.gl/AFskqB'
+      )
+    },
+    registered () {
+      console.log('Service worker has been registered.')
+    },
+    cached () {
+      console.log('Content has been cached for offline use.')
+    },
+    updatefound () {
+      console.log('New content is downloading.')
+    },
+    updated () {
+      console.log('New content is available; please refresh.')
+    },
+    offline () {
+      console.log('No internet connection found. App is running in offline mode.')
+    },
+    error (error) {
+      console.error('Error during service worker registration:', error)
+    }
+  })
+}

+ 51 - 0
src/router/index.js

@@ -0,0 +1,51 @@
+import { createRouter, createWebHashHistory  } from 'vue-router'
+
+const routes = [
+  {
+    path: '/',
+    name: 'Invoice',
+    component: () => import('../views/homePage/index.vue')
+  },
+  {
+    path: '/tablePage',
+    name: 'tablePage',
+    component: () => import( '../views/tablePage/index.vue')
+  },
+  {
+    path: '/tablePage1',
+    name: 'tablePage1',
+    component: () => import( '../views/tablePage1/index.vue')
+  },
+  {
+    path: '/tablePage2',
+    name: 'tablePage2',
+    component: () => import( '../views/tablePage2/index.vue')
+  },
+  {
+    path: '/tablePage3',
+    name: 'tablePage3',
+    component: () => import( '../views/tablePage3/index.vue')
+  },
+  {
+    path: '/fault',
+    name: 'fault',
+    component: () => import( '../views/entry/fault.vue')
+  },
+  {
+    path: '/maintain',
+    name: 'maintain',
+    component: () => import( '../views/entry/maintain.vue')
+  },
+  {
+    path: '/affected',
+    name: 'affected',
+    component: () => import( '../views/entry/affected.vue')
+  }
+]
+
+const router = createRouter({
+  history: createWebHashHistory(),
+  routes
+})
+
+export default router

+ 23 - 0
src/store/index.js

@@ -0,0 +1,23 @@
+import { createStore } from 'vuex'
+
+// 创建一个新的 store 实例
+const store = createStore({
+     // 值的存储  获取: this.$store.state.xxxx
+     state() {
+          return {
+              
+          }
+     },
+
+     //计算state的值  获取: this.$store.getters.xxxx
+     getters: {
+         
+     },
+
+     // 数据更新 使用: this.$store.commit('函数名','val')
+     mutations: {
+     
+     }
+})
+
+export default store

+ 177 - 0
src/utils/Blob.js

@@ -0,0 +1,177 @@
+/* eslint-disable */
+/* Blob.js
+ * A Blob implementation.
+ * 2014-05-27
+ *
+ * By Eli Grey, http://eligrey.com
+ * By Devin Samarin, https://github.com/eboyjr
+ * License: X11/MIT
+ *   See LICENSE.md
+ */
+
+/*global self, unescape */
+/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
+ plusplus: true */
+
+/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
+
+const blob = function (view) {
+  "use strict";
+
+  view.URL = view.URL || view.webkitURL;
+
+  if (view.Blob && view.URL) {
+    try {
+      new Blob;
+      return;
+    } catch (e) {}
+  }
+
+  // Internally we use a BlobBuilder implementation to base Blob off of
+  // in order to support older browsers that only have BlobBuilder
+  var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function (view) {
+    var
+      get_class = function (object) {
+        return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
+      },
+      FakeBlobBuilder = function BlobBuilder() {
+        this.data = [];
+      },
+      FakeBlob = function Blob(data, type, encoding) {
+        this.data = data;
+        this.size = data.length;
+        this.type = type;
+        this.encoding = encoding;
+      },
+      FBB_proto = FakeBlobBuilder.prototype,
+      FB_proto = FakeBlob.prototype,
+      FileReaderSync = view.FileReaderSync,
+      FileException = function (type) {
+        this.code = this[this.name = type];
+      },
+      file_ex_codes = (
+        "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " +
+        "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
+      ).split(" "),
+      file_ex_code = file_ex_codes.length,
+      real_URL = view.URL || view.webkitURL || view,
+      real_create_object_URL = real_URL.createObjectURL,
+      real_revoke_object_URL = real_URL.revokeObjectURL,
+      URL = real_URL,
+      btoa = view.btoa,
+      atob = view.atob
+
+      ,
+      ArrayBuffer = view.ArrayBuffer,
+      Uint8Array = view.Uint8Array;
+    FakeBlob.fake = FB_proto.fake = true;
+    while (file_ex_code--) {
+      FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
+    }
+    if (!real_URL.createObjectURL) {
+      URL = view.URL = {};
+    }
+    URL.createObjectURL = function (blob) {
+      var
+        type = blob.type,
+        data_URI_header;
+      if (type === null) {
+        type = "application/octet-stream";
+      }
+      if (blob instanceof FakeBlob) {
+        data_URI_header = "data:" + type;
+        if (blob.encoding === "base64") {
+          return data_URI_header + ";base64," + blob.data;
+        } else if (blob.encoding === "URI") {
+          return data_URI_header + "," + decodeURIComponent(blob.data);
+        }
+        if (btoa) {
+          return data_URI_header + ";base64," + btoa(blob.data);
+        } else {
+          return data_URI_header + "," + encodeURIComponent(blob.data);
+        }
+      } else if (real_create_object_URL) {
+        return real_create_object_URL.call(real_URL, blob);
+      }
+    };
+    URL.revokeObjectURL = function (object_URL) {
+      if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
+        real_revoke_object_URL.call(real_URL, object_URL);
+      }
+    };
+    FBB_proto.append = function (data /*, endings*/ ) {
+      var bb = this.data;
+      // decode data to a binary string
+      if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
+        var
+          str = "",
+          buf = new Uint8Array(data),
+          i = 0,
+          buf_len = buf.length;
+        for (; i < buf_len; i++) {
+          str += String.fromCharCode(buf[i]);
+        }
+        bb.push(str);
+      } else if (get_class(data) === "Blob" || get_class(data) === "File") {
+        if (FileReaderSync) {
+          var fr = new FileReaderSync;
+          bb.push(fr.readAsBinaryString(data));
+        } else {
+          // async FileReader won't work as BlobBuilder is sync
+          throw new FileException("NOT_READABLE_ERR");
+        }
+      } else if (data instanceof FakeBlob) {
+        if (data.encoding === "base64" && atob) {
+          bb.push(atob(data.data));
+        } else if (data.encoding === "URI") {
+          bb.push(decodeURIComponent(data.data));
+        } else if (data.encoding === "raw") {
+          bb.push(data.data);
+        }
+      } else {
+        if (typeof data !== "string") {
+          data += ""; // convert unsupported types to strings
+        }
+        // decode UTF-16 to binary string
+        bb.push(unescape(encodeURIComponent(data)));
+      }
+    };
+    FBB_proto.getBlob = function (type) {
+      if (!arguments.length) {
+        type = null;
+      }
+      return new FakeBlob(this.data.join(""), type, "raw");
+    };
+    FBB_proto.toString = function () {
+      return "[object BlobBuilder]";
+    };
+    FB_proto.slice = function (start, end, type) {
+      var args = arguments.length;
+      if (args < 3) {
+        type = null;
+      }
+      return new FakeBlob(
+        this.data.slice(start, args > 1 ? end : this.data.length), type, this.encoding
+      );
+    };
+    FB_proto.toString = function () {
+      return "[object Blob]";
+    };
+    FB_proto.close = function () {
+      this.size = this.data.length = 0;
+    };
+    return FakeBlobBuilder;
+  }(view));
+
+  view.Blob = function Blob(blobParts, options) {
+    var type = options ? (options.type || "") : "";
+    var builder = new BlobBuilder();
+    if (blobParts) {
+      for (var i = 0, len = blobParts.length; i < len; i++) {
+        builder.append(blobParts[i]);
+      }
+    }
+    return builder.getBlob(type);
+  };
+}
+exports.blob = blob;

+ 274 - 0
src/utils/Export2Excel.js

@@ -0,0 +1,274 @@
+//Export2Excel.js
+/* eslint-disable */
+require('script-loader!file-saver');
+require('./Blob.js');//转二进制用  这边要写你的blob的实际地址
+require('script-loader!xlsx/dist/xlsx.core.min');
+
+function generateArray(table) {
+  var out = [];
+  var rows = table.querySelectorAll('tr');
+  var ranges = [];
+  for (var R = 0; R < rows.length; ++R) {
+    var outRow = [];
+    var row = rows[R];
+    var columns = row.querySelectorAll('td');
+    for (var C = 0; C < columns.length; ++C) {
+      var cell = columns[C];
+      var colspan = cell.getAttribute('colspan');
+      var rowspan = cell.getAttribute('rowspan');
+      var cellValue = cell.innerText;
+      if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
+
+      //Skip ranges
+      ranges.forEach(function (range) {
+        if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
+          for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
+        }
+      });
+
+      //Handle Row Span
+      if (rowspan || colspan) {
+        rowspan = rowspan || 1;
+        colspan = colspan || 1;
+        ranges.push({
+          s: {
+            r: R,
+            c: outRow.length
+          },
+          e: {
+            r: R + rowspan - 1,
+            c: outRow.length + colspan - 1
+          }
+        });
+      };
+
+      //Handle Value
+      outRow.push(cellValue !== "" ? cellValue : null);
+
+      //Handle Colspan
+      if (colspan)
+        for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
+    }
+    out.push(outRow);
+  }
+  return [out, ranges];
+};
+
+function datenum(v, date1904) {
+  if (date1904) v += 1462;
+  var epoch = Date.parse(v);
+  return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
+}
+
+function sheet_from_array_of_arrays(data, opts) {
+  var ws = {};
+  var range = {
+    s: {
+      c: 10000000,
+      r: 10000000
+    },
+    e: {
+      c: 0,
+      r: 0
+    }
+  };
+  for (var R = 0; R != data.length; ++R) {
+    for (var C = 0; C != data[R].length; ++C) {
+      if (range.s.r > R) range.s.r = R;
+      if (range.s.c > C) range.s.c = C;
+      if (range.e.r < R) range.e.r = R;
+      if (range.e.c < C) range.e.c = C;
+      var cell = {
+        v: data[R][C]
+      };
+      if (cell.v == null) continue;
+      var cell_ref = XLSX.utils.encode_cell({
+        c: C,
+        r: R
+      });
+
+      if (typeof cell.v === 'number') cell.t = 'n';
+      else if (typeof cell.v === 'boolean') cell.t = 'b';
+      else if (cell.v instanceof Date) {
+        cell.t = 'n';
+        cell.z = XLSX.SSF._table[14];
+        cell.v = datenum(cell.v);
+      } else cell.t = 's';
+
+      ws[cell_ref] = cell;
+    }
+  }
+  if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
+  return ws;
+}
+
+function Workbook() {
+  if (!(this instanceof Workbook)) return new Workbook();
+  this.SheetNames = [];
+  this.Sheets = {};
+}
+
+function s2ab(s) {
+  var buf = new ArrayBuffer(s.length);
+  var view = new Uint8Array(buf);
+  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
+  return buf;
+}
+
+export function export_table_to_excel(id) {
+  var theTable = document.getElementById(id);
+  var oo = generateArray(theTable);
+  var ranges = oo[1];
+
+  /* original data */
+  var data = oo[0];
+  var ws_name = "风机数据";
+
+  var wb = new Workbook(),
+    ws = sheet_from_array_of_arrays(data);
+
+  /* add ranges to worksheet */
+  // ws['!cols'] = ['apple', 'banan'];
+  ws['!merges'] = ranges;
+
+  /* add worksheet to workbook */
+  wb.SheetNames.push(ws_name);
+  wb.Sheets[ws_name] = ws;
+
+  var wbout = XLSX.write(wb, {
+    bookType: 'xlsx',
+    bookSST: false,
+    type: 'binary'
+  });
+
+  saveAs(new Blob([s2ab(wbout)], {
+    type: "application/octet-stream"
+  }), "test.xlsx")
+}
+
+function formatJson(jsonData) {
+}
+export function export_json_to_excel(th, jsonData, defaultTitle) {
+
+  /* original data */
+
+  var data = jsonData;
+  data.unshift(th);
+  var ws_name = "导出的Excel";
+
+  var wb = new Workbook(),
+    ws = sheet_from_array_of_arrays(data);
+
+
+  /* add worksheet to workbook */
+  wb.SheetNames.push(ws_name);
+  wb.Sheets[ws_name] = ws;
+
+  var wbout = XLSX.write(wb, {
+    bookType: 'xlsx',
+    bookSST: false,
+    type: 'binary'
+  });
+  var title = defaultTitle || '列表'
+  saveAs(new Blob([s2ab(wbout)], {
+    type: "application/octet-stream"
+  }), title + ".xlsx")
+};
+
+export function export_blob(th, jsonData, defaultTitle) {
+  var data = jsonData;
+  data.unshift(th);
+  var ws_name = "风机数据";
+  var wb = new Workbook(),
+    ws = sheet_from_array_of_arrays(data);
+  /* add worksheet to workbook */
+  wb.SheetNames.push(ws_name);
+  wb.Sheets[ws_name] = ws;
+  var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' });
+
+  if (defaultTitle) {//只渲染一个excel
+    saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), defaultTitle + ".xlsx")
+  } else {//返回多个blob
+    var aaa = new Blob([s2ab(wbout)], { type: 'text/plain' });
+    return aaa;
+  }
+};
+
+export function export_more_blob(th, jsonData, defaultTitle) {
+  var data = jsonData;
+  //添加标题
+  for (var i = 0; i < th.length; i++) {
+    data[i].unshift(th[i])
+  }
+  //这里是定义sheet的名称 有几个sheet就加几个
+  var ws_name = ["日上网电量", "上网功率", "测风塔数据"];
+  var wb = new Workbook(), ws = [];
+  //数据转换
+  for (var j = 0; j < th.length; j++) {
+    ws.push(sheet_from_array_of_arrays(data[j]))
+  }
+  /* add worksheet to workbook */
+  //生成多个sheet
+  for (var k = 0; k < th.length; k++) {
+    wb.SheetNames.push(ws_name[k])
+    wb.Sheets[ws_name[k]] = ws[k]
+  }
+
+  var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' });
+
+  if (defaultTitle) {//只渲染一个excel
+    saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), defaultTitle + ".xlsx")
+  } else {//返回多个blob
+    var aaa = new Blob([s2ab(wbout)], { type: 'text/plain' });
+    return aaa;
+  }
+}
+
+export function exportMultiple(thArray, dataArray, sheetNameArray, fileName = "导出的Excel") {
+
+  let ws_name = sheetNameArray;
+  let wb = new Workbook();
+  let ws = [];
+  let filterArray = [];
+
+  const formatJson = function (filterVal, jsonData) {
+    return jsonData.map(v => filterVal.map(j => v[j]));
+  };
+
+  thArray.forEach((pEle, pIndex) => {
+    ws.push([]);
+    dataArray[pIndex].unshift(pEle);
+    filterArray.push([]);
+    pEle.forEach(cEle => {
+      filterArray[pIndex].push(cEle.field);
+    });
+  });
+
+  thArray.forEach((pEle, pIndex) => {
+    const data = formatJson(filterArray[pIndex], dataArray[pIndex]);
+    ws[pIndex].push(sheet_from_array_of_arrays(data));
+    wb.SheetNames.push(ws_name[pIndex]);
+    wb.Sheets[ws_name[pIndex]] = ws[pIndex][0];
+  });
+
+
+  let cellKes = []
+  for (var i = 0; i < 26; i++) {
+    cellKes.push(String.fromCharCode(65 + i));
+  }
+
+  let idx = 0;
+  ws.forEach((pEle, pIndex) => {
+    idx = 0
+    thArray[pIndex].forEach(thEle => {
+      pEle.forEach(cEle => {
+        cEle[cellKes[idx] + 1] = { v: thEle.name, t: "s" }
+        idx++;
+      });
+    });
+  });
+
+  let wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: false, type: 'binary' });
+  saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), fileName + ".xlsx");
+
+}

+ 12 - 0
src/utils/exportExcel.js

@@ -0,0 +1,12 @@
+// 导出的方法  tHeader => 设置Excel的表格第一行的标题  filterVal => 对象的属性key值 被导出listData => 导出数据  => 导出(文件)名称
+import { export_json_to_excel } from "./Export2Excel"; //引入文件
+
+export function outExportExcel(tHeader = [], filterVal = [], listData = [], exportName = new Date().getTime()) {
+    // 注意这个Export2Excel路径
+    const data = formatJson(filterVal, listData);
+    export_json_to_excel(tHeader, data, exportName);
+}
+
+function formatJson(filterVal, jsonData) {
+    return jsonData.map(v => filterVal.map(j => v[j]))
+}

+ 56 - 0
src/utils/request.js

@@ -0,0 +1,56 @@
+import axios from "axios";
+import store from '../store/index'
+// import { getToken } from "@/utils/storage";
+const service = axios.create();
+// import { Loading } from 'element-ui';
+// import { Message  } from 'element-ui';
+service.defaults.timeout = 50000;
+// service.defaults.baseURL = `${process.env.VUE_APP_API}`
+service.interceptors.request.use(
+	config => {
+		// 加载开始
+		// this.$loading({
+		// 	lock: true,
+		// 	text: 'Loading',
+		// 	spinner: 'el-icon-loading',
+		// 	background: 'rgba(0, 0, 0, 0.7)'
+		// });
+		// Loading.start(),
+		config.headers = {
+            // 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
+            Authorization: store.state.token,
+        }
+		return config;
+	},
+	error => {
+		return Promise.reject(error);
+	}
+);
+
+service.interceptors.response.use(
+	// Loading.close(),
+	response => {
+		// 处理正常返回数据
+		// const { status } = response;
+		// if (
+		// 	status === 200
+		// ) {
+		// 	return response ;
+		// } else {
+		// 	return false;
+		// }
+		return response ;
+	},
+	error => {
+		// 处理错误并给出相应的错误处理
+		if (error.response) {
+			// const { status } = error.response;
+			// tips[status](error);
+			return error.response.data
+		}else{
+			return false;
+		}
+	}
+);
+
+export default service;

+ 28 - 0
src/utils/storage.js

@@ -0,0 +1,28 @@
+import Cookies from "js-cookie";
+// import storage from "good-storage";
+// const user = 'userInfo'
+// const token = 'token'
+const TokenKey = "Authorization";
+// 获取user
+// const getUser = () => {
+//     return getStorageSync(user)
+// }
+
+// 设置user
+// export const setUser = key => {
+//     return setStorageSync(user, key)
+// }
+
+// 获取token
+export function getToken() {
+    return Cookies.get(TokenKey);
+}
+
+// 设置token
+export const setToken = (token) => {
+    return Cookies.set(TokenKey, token);
+};
+export default {
+	getToken,
+	setToken,
+}

+ 516 - 0
src/views/entry/affected.vue

@@ -0,0 +1,516 @@
+<template>
+    <div>
+        <div class="title-list">
+            <div class="search">
+                <div class="date">风场:</div>
+                <el-select class="inputs" v-model="selectValue" placeholder="请选择" @change="handleChange">
+                    <el-option v-for="item in stationList" :key="item.name" :label="item.aname" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="query-item">
+                <div class="lable">开始日期:</div>
+                <div class="search-input">
+                    <el-date-picker v-model="timeValue" type="datetimerange" range-separator="至"
+                        start-placeholder="开始日期" end-placeholder="结束日期">
+                    </el-date-picker>
+                </div>
+            </div>
+            <div class="search">
+                <div class="date">类型:</div>
+                <el-select class="inputs" clearable v-model="typeStatus" placeholder="请选择">
+                    <el-option v-for="item in typeList" :key="item.id" :label="item.name" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="query-actions">
+                <button class="button" @click="getDatas">查询</button>
+                <button class="button" @click="add">新增</button>
+                <button class="button" @click="exportExcel">导出</button>
+            </div>
+        </div>
+        <div>
+            <el-table height="90vh" ref="multipleTable" empty-text="暂无数据" :data="tableList" stripe
+                style="width: 100%; margin-bottom: 10px">
+                <el-table-column prop="linename" label="线路" align="center" sortable></el-table-column>
+                <el-table-column label="开始日期" prop="showbegindate" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="结束日期" prop="showenddate" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="分类" prop="typeName" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="损失电量" prop="powerloss" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="受累时长" prop="faultduration" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="操作" align="center">
+                    <template #default="scope">
+                        <el-button type="text" style="color: #597ef7" @click="handleEdit(scope.row)">编辑</el-button>
+                        <el-button type="text" style="color: #b3bdc0" @click="handleDelete(scope.row)">删除</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <el-dialog v-model="dialogVisible" title="受累管理" width="45%" top="10vh" :show-close="true">
+            <div class="table-list">
+                <div class="lists">
+                    <div class="rows">
+                        <div class="rows-name">风场:</div>
+                        <el-input class="rows-inputs" v-model="sendData.stationName" disabled></el-input>
+                    </div>
+                    <div class="rows">
+                        <div class="rows-name">类型:</div>
+                        <el-select class="inputs" clearable v-model="sendData.type" placeholder="请选择">
+                            <el-option v-for="item in typeList" :key="item.id" :label="item.name" :value="item.id">
+                            </el-option>
+                        </el-select>
+                    </div>
+                </div>
+                <div class="lists">
+                    <div class="rows">
+                        <div class="rows-name">开始时间:</div>
+                        <el-date-picker v-model="sendData.begindate" type="datetime" placeholder="选择开始时间" :disabled="isEdit">
+                        </el-date-picker>
+                    </div>
+                    <div class="rows">
+                        <div class="rows-name">结束时间:</div>
+                        <el-date-picker v-model="sendData.enddate" type="datetime" placeholder="选择结束时间" :disabled="isEdit">
+                        </el-date-picker>
+                    </div>
+                </div>
+                <div class="lists" style="margin-bottom: 40px">
+                    <div class="rows">
+                        <div class="rows-name">损失电量:</div>
+                        <el-input class="rows-inputs" v-model="sendData.ssdl" placeholder="请输入损失电量"></el-input>
+                    </div>
+                </div>
+                <div class="lists" v-if="!isEdit">
+                    <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
+                </div>
+                <div class="lists" v-if="!isEdit">
+                    <el-checkbox-group v-model="choseLineList" @change="handleCheckedCitiesChange">
+                        <el-checkbox  v-for="(item, index) in lineList" :key="index" :label="item.name"></el-checkbox>
+                    </el-checkbox-group>
+                </div>
+            </div>
+            <div class="submit">
+                <el-button type="primary" plain @click="sunmit">提交</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import api from "api/index";
+import dayjs from "dayjs";
+import XLSX from "xlsx";
+export default {
+    data() {
+        return {
+            timeValue: [],
+            stationList: [
+                {
+                    "id": "WNS_FDC",
+                    "code": "WNS_FDC",
+                    "name": "太旗卧牛山风电场",
+                    "address": "太旗卧牛山风电场",
+                    "telephone": null,
+                    "capacity": 148.5,
+                    "capacityunit": "MW",
+                    "quantity": 99,
+                    "aname": "卧牛山风电场",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP77-1500/UP77-1500-1/UP77-1500-2",
+                    "ordernum": 1,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "YY_FDC",
+                    "code": "YY_FDC",
+                    "name": "右玉高家堡风电场  ",
+                    "address": "右玉高家堡风电场  ",
+                    "telephone": null,
+                    "capacity": 198,
+                    "capacityunit": "MW",
+                    "quantity": 132,
+                    "aname": "高家堡风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP82-1500/UP82-1500-1/UP86-1500/UP86-1500-1/UP86-1500-2/UP86-1500-3/UP86-1500-4/MY-1.5se",
+                    "ordernum": 2,
+                    "altitude": 1000,
+                    "height": null
+                },
+            ],
+            selectValue: '',
+            typeStatus: '',
+            lineList: [
+                {
+                    "id": "WNS01_XL",
+                    "code": "WNS01_XL",
+                    "aname": "卧牛山一号集电线路",
+                    "aname": null,
+                    "projectid": "WNS01_GC",
+                    "ordernum": 1,
+                    "capacity": 16,
+                    "capacityunit": "MV",
+                    "quantity": 10
+                },
+                {
+                    "id": "WNS02_XL",
+                    "code": "WNS02_XL",
+                    "aname": "卧牛山二号集电线路",
+                    "aname": null,
+                    "projectid": "WNS01_GC",
+                    "ordernum": 2,
+                    "capacity": 16,
+                    "capacityunit": "MV",
+                    "quantity": 11
+                },
+            ],
+            typeList: [
+                {
+                    "id": "cngz",
+                    "name": "输变电非计划检修"
+                },
+                {
+                    "id": "cnjx",
+                    "name": "输变电计划检修"
+                },
+                {
+                    "id": "dwgz",
+                    "name": "电网故障"
+                },
+                {
+                    "id": "dwjx",
+                    "name": "电网计划检修"
+                },
+                {
+                    "id": "tqsl",
+                    "name": "天气受累"
+                }
+            ],
+            tableList: [
+                {
+                    "id": "1",
+                    "projectid": "1",
+                    "projectname": "1",
+                    "wpid": "WNS_FDC",
+                    "wpname": "1",
+                    "lineid": "1",
+                    "linename": "1",
+                    "begindate": "2022-10-31T16:00:00.000+0000",
+                    "enddate": "2022-10-31T16:00:00.000+0000",
+                    "faulttype": "cngz",
+                    "powerloss": 1,
+                    "faultduration": 1
+                },
+            ],
+            dialogVisible: false,
+            sendData: {
+                begindate: '',
+                enddate: '',
+                lines: [],
+                ssdl: '',
+                type: '',
+                wpid: this.selectValue,
+                stationName: this.stationList?.find(val => val.code === this.selectValue).aname,
+            },
+            isEdit: false,
+            checkAll: false,
+        isIndeterminate: true,
+        allLines:['卧牛山一号集电线路','卧牛山二号集电线路'],
+        choseLineList: [],
+        };
+    },
+    created() {
+        let date = new Date();
+        this.timeValue[0] = new Date(new Date(new Date().toLocaleDateString()).getTime());
+        this.timeValue[1] = date.getTime();
+        this.getStation()
+    },
+    methods: {
+        handleChange(){
+            let lines = []
+            api.getLines({
+                wpid: this.selectValue
+            }).then(res => {
+                if (res.data) {
+                    this.lineList = res.data.data
+                    res.data.data.forEach(item =>{
+                        lines.push(item.name)
+                    })
+                }
+            })
+            this.allLines = lines
+            this.choseLineList = []
+            this.getDatas()
+        },
+        async getStation() {
+            await api.getStation().then(res => {
+                if (res.data) {
+                    let arr = [
+                        {
+                            id: '',
+                            aname: '全部'
+                        }
+                    ]
+                    this.stationList = [ ...arr , ...res.data.data]
+                    console.log(this.stationList);
+                    this.selectValue = this.stationList[0].id
+                }
+            })
+            await api.getLines({
+                wpid: this.selectValue
+            }).then(res => {
+                if (res.data) {
+                    this.lineList = res.data.data
+                    res.data.data.forEach(item =>{
+                        this.allLines.push(item.name)
+                    })
+                }
+            })
+            await api.getslStatus().then(res => {
+                if (res.data) {
+                    this.typeList = res.data.data
+                }
+            })
+            this.getDatas()
+        },
+        getDatas() {
+            api.involved({
+                wpid: this.selectValue,
+                begin: new Date(this.timeValue[0]).getTime(),
+                end: new Date(this.timeValue[1]).getTime(),
+            }).then(res => {
+                if (res.data) {
+                    res.data.data.forEach(item => {
+                        item.showbegindate = dayjs(item.begindate).format("YYYY-MM-DD HH:mm:ss")
+                        item.showenddate = dayjs(item.enddate).format("YYYY-MM-DD HH:mm:ss")
+                        item.typeName = this.typeList.find(val => val.id === item.faulttype)?.name
+                    })
+                    this.tableList = res.data.data
+                }
+            })
+        },
+        add() {
+            this.sendData = {
+                begindate: '',
+                enddate: '',
+                lines: [
+                ],
+                ssdl: '',
+                type: '',
+                wpid: this.selectValue,
+                stationName: this.stationList.find(val => val.code === this.selectValue).aname,
+            }
+            this.dialogVisible = true
+            this.isEdit = false
+        },
+        sunmit() {
+            this.sendData.lines = []
+            if (this.isEdit) {
+                let pairs = this.tableList.find(val => val.id === this.sendData.id)
+                pairs.powerloss = this.sendData.ssdl
+                pairs.faulttype = this.sendData.type
+                api.involvedEdit(pairs).then(res => {
+                    if (res.data) {
+                        this.$message({
+                            type: 'success',
+                            message: '修改成功!'
+                        });
+                        this.dialogVisible = false
+                        this.getDatas()
+                    }
+                })
+            } else {
+                console.log(this.choseLineList);
+                this.sendData.begindate = new Date(this.sendData.begindate).getTime()
+                this.sendData.enddate = new Date(this.sendData.enddate).getTime()
+                this.choseLineList.forEach(item =>{
+                    let obj = this.lineList.find(val => val.name === item)
+                    this.sendData.lines.push(obj)
+                })
+                let pairs = {}
+                pairs.wpid = this.sendData.wpid
+                pairs.lines = this.sendData.lines
+                pairs.begin = this.sendData.begindate
+                pairs.end = this.sendData.enddate
+                pairs.ssdl = this.sendData.ssdl
+                pairs.type = this.sendData.type
+                console.log(pairs);
+                api.involvedAdd(pairs).then(res => {
+                    if (res.data) {
+                        this.$message({
+                            type: 'success',
+                            message: '添加成功!'
+                        });
+                        this.dialogVisible = false
+                        this.getDatas()
+                    }
+                })
+            }
+        },
+        handleEdit(val) {
+            this.sendData = {
+                id:val.id,
+                begindate: val.begindate,
+                enddate: val.enddate,
+                ssdl: val.powerloss,
+                type: val.faulttype,
+                wpid: this.selectValue,
+                stationName: this.stationList.find(val => val.code === this.selectValue).aname,
+            }
+            this.isEdit = true
+            this.dialogVisible = true
+
+        },
+        handleDelete(val) {
+            this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                api.involvedDel({
+                    id: val.id
+                }).then(res => {
+                    if (res.data) {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.getDatas()
+                    }
+                })
+
+            }).catch(() => {
+                this.$message({
+                    type: 'info',
+                    message: '已取消删除'
+                });
+            });
+        },
+        handleCheckAllChange(val) {
+            this.choseLineList = val ? this.allLines : [];
+            this.isIndeterminate = false;
+      }, 
+        exportExcel() {
+            // 数据源
+            let data = [];
+            this.tableList.forEach((item) => {
+                let values = {
+                    线路: item.linename,
+                    开始时间: item.showbegindate,
+                    结束时间: item.showenddate,
+                    分类: item.faulttype,
+                    损失电量: item.powerloss,
+                    受累时长: item.faultduration,
+                    内报外报: item.type,
+                };
+                data.push(values);
+            });
+            // 下载的路径
+            let fileName = `受累管理.xlsx`;
+            let filePath = fileName;
+            // 新建workbook
+            const wb = XLSX.utils.book_new();
+            // 新建worksheet,并载入数据
+            const ws = XLSX.utils.json_to_sheet(data);
+            // 设置每列的列宽,10代表10个字符,注意中文占2个字符
+            ws["!cols"] = [{ wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 25 }, { wch: 25 },];
+            // 生成xlsx文件(workbook,worksheet数据,sheet命名)
+            XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
+
+            // 写文件(workbook,xlsx文件路径+文件名)
+            XLSX.writeFile(wb, filePath);
+        },
+    },
+}
+</script>
+<style lang="less" scoped>
+.title-list {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-top: 10px;
+
+    .search {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .date {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .query-item {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .lable {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .button {
+        width: 80px;
+        height: 40px;
+        margin-left: 30px;
+    }
+}
+
+.table-list {
+    min-height: 40vh;
+}
+
+.lists {
+    width: 90%;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-between;
+    margin: 0 5% 20px 5%;
+}
+
+.rows {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+
+    .rows-name {
+        width: 100px;
+    }
+
+    .rows-input {
+        width: 400px;
+    }
+
+    .rows-inputs {
+        width: 220px;
+    }
+}
+
+.submit {
+    position: absolute;
+    right: 20px;
+    bottom: 20px;
+}
+</style>

+ 560 - 0
src/views/entry/fault.vue

@@ -0,0 +1,560 @@
+<template>
+    <div>
+        <div class="title-list">
+            <!-- <div class="search">
+                <div class="date">机组:</div>
+                <el-cascader v-model="selectValue" :options="stationList" :props="defaultProps"
+                    :show-all-levels="false"></el-cascader>
+            </div> -->
+            <div class="search">
+                <div class="date">风场:</div>
+                <el-select class="inputs" v-model="selectValue" placeholder="请选择" @change="handleChange()">
+                    <el-option v-for="item in stationList" :key="item.aname" :label="item.aname" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="search">
+                <div class="date">机组:</div>
+                <el-select class="inputs" clearable v-model="groupId" placeholder="请选择">
+                    <el-option v-for="item in groupList" :key="item.code" :label="item.code" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="query-item">
+                <div class="lable">开始日期:</div>
+                <div class="search-input">
+                    <el-date-picker v-model="timeValue" type="datetimerange" range-separator="至"
+                        start-placeholder="开始日期" end-placeholder="结束日期">
+                    </el-date-picker>
+                </div>
+            </div>
+            <div class="search">
+                <div class="date">类型:</div>
+                <el-select class="inputs" clearable v-model="typeStatus" placeholder="请选择">
+                    <el-option v-for="item in typeList" :key="item.name" :label="item.name" :value="item.name">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="query-actions">
+                <button class="button" @click="getDatas">查询</button>
+                <button class="button" @click="add">新增</button>
+                <button class="button" @click="exportExcel">导出</button>
+            </div>
+        </div>
+        <div>
+            <el-table height="90vh" ref="multipleTable" empty-text="暂无数据" :data="tableList" stripe
+                style="width: 100%; margin-bottom: 10px">
+                <el-table-column prop="projectname" label="期次" align="center" width="220" sortable></el-table-column>
+                <el-table-column label="场站名称" prop="wpname" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="风机名称" prop="wtname" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="开始时间" prop="showbegindate" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="结束时间" prop="showenddate" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="故障分类" prop="faulttype" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="故障现象" prop="faultphenomenon" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="消缺工艺" prop="defecteliminating" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="处理结果" prop="processingresults" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="损失电量" prop="powerloss" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="故障时长" prop="faultduration" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="时长影响容量" prop="impactcapacity" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="内报/外报" prop="type" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="操作" align="center">
+                    <template #default="scope">
+                        <el-button type="text" style="color: #597ef7" @click="handleEdit(scope.row)">编辑</el-button>
+                        <el-button type="text" style="color: #b3bdc0" @click="handleDelete(scope.row)">删除</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <el-dialog v-model="dialogVisible" title="逆变器详情" width="45%" top="10vh" :show-close="true">
+            <div class="table-list">
+                <div class="lists">
+                    <div class="rows">
+                        <div class="rows-name">开始时间:</div>
+                        <el-date-picker v-model="sendData.begindate" type="datetime" placeholder="选择开始时间">
+                        </el-date-picker>
+                    </div>
+                    <div class="rows">
+                        <div class="rows-name">结束时间:</div>
+                        <el-date-picker v-model="sendData.enddate" type="datetime" placeholder="选择结束时间">
+                        </el-date-picker>
+                    </div>
+                </div>
+                <div class="lists">
+                    <div class="rows">
+                        <div class="rows-name">类型:</div>
+                        <el-select class="inputs" clearable v-model="sendData.faulttype" placeholder="请选择">
+                            <el-option v-for="item in typeList" :key="item.name" :label="item.name" :value="item.name">
+                            </el-option>
+                        </el-select>
+                    </div>
+                    <div class="rows">
+                        <div class="rows-name">处理结果:</div>
+                        <el-select class="inputs" clearable v-model="sendData.processingresults" placeholder="请选择">
+                            <el-option v-for="item in resultsList" :key="item.name" :label="item.name"
+                                :value="item.name">
+                            </el-option>
+                        </el-select>
+                    </div>
+                </div>
+                <div class="lists">
+                    <div class="rows">
+                        <div class="rows-name">故障现象:</div>
+                        <el-input type="textarea" class="rows-input" v-model="sendData.faultphenomenon"
+                            placeholder="请输入故障现象"></el-input>
+                    </div>
+                </div>
+                <div class="lists">
+                    <div class="rows">
+                        <div class="rows-name">消缺工艺:</div>
+                        <el-input type="textarea" class="rows-input" v-model="sendData.defecteliminating"
+                            placeholder="请输入消缺工艺"></el-input>
+                    </div>
+                </div>
+                <div class="lists" style="margin-bottom: 40px">
+                    <div class="rows">
+                        <div class="rows-name">损失电量:</div>
+                        <el-input class="rows-inputs" v-model="sendData.powerloss" placeholder="请输入损失电量"></el-input>
+                    </div>
+                    <div class="rows">
+                        <div class="rows-name">内报/外报:</div>
+                        <el-select class="inputs" clearable v-model="sendData.type" placeholder="请选择">
+                            <el-option v-for="item in typesList" :key="item.name" :label="item.name" :value="item.name">
+                            </el-option>
+                        </el-select>
+                    </div>
+                </div>
+            </div>
+            <div class="submit">
+                <el-button type="primary" plain @click="sunmit">提交</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import api from "api/index";
+import dayjs from "dayjs";
+import XLSX from "xlsx";
+export default {
+    data() {
+        return {
+            timeValue: [],
+            groupId: '',
+            groupList: [
+            ],
+            stationList: [
+                {
+                    "id": "WNS_FDC",
+                    "code": "WNS_FDC",
+                    "name": "太旗卧牛山风电场",
+                    "address": "太旗卧牛山风电场",
+                    "telephone": null,
+                    "capacity": 148.5,
+                    "capacityunit": "MW",
+                    "quantity": 99,
+                    "aname": "卧牛山风电场",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP77-1500/UP77-1500-1/UP77-1500-2",
+                    "ordernum": 1,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "YY_FDC",
+                    "code": "YY_FDC",
+                    "name": "右玉高家堡风电场  ",
+                    "address": "右玉高家堡风电场  ",
+                    "telephone": null,
+                    "capacity": 198,
+                    "capacityunit": "MW",
+                    "quantity": 132,
+                    "aname": "高家堡风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP82-1500/UP82-1500-1/UP86-1500/UP86-1500-1/UP86-1500-2/UP86-1500-3/UP86-1500-4/MY-1.5se",
+                    "ordernum": 2,
+                    "altitude": 1000,
+                    "height": null
+                },
+            ],
+            defaultProps: {
+                children: "data",
+                label: 'code',
+                value: 'id',
+            },
+            selectValue: ['', 'GJY01_001'],
+            typeStatus: '',
+            typeList: [
+                {
+                    name: '变频器',
+                },
+                {
+                    name: '发电机',
+                },
+                {
+                    name: '齿轮箱',
+                },
+                {
+                    name: '箱变',
+                },
+                {
+                    name: '偏航系统',
+                },
+                {
+                    name: '液压站',
+                },
+                {
+                    name: '电网',
+                },
+                {
+                    name: '风速风向',
+                },
+                {
+                    name: '主轴',
+                },
+                {
+                    name: '变桨系统',
+                },
+                {
+                    name: '安全链',
+                },
+                {
+                    name: '机舱柜',
+                },
+                {
+                    name: '塔底柜',
+                },
+                {
+                    name: '塔筒',
+                },
+                {
+                    name: '机舱',
+                },
+                {
+                    name: '其他',
+                },
+            ],
+            tableList: [
+                {
+                    "id": "9686572cc51048e09b731ab05a231ec4",
+                    "projectid": "GJY01_GC",
+                    "projectname": "平鲁高家堰一期工程",
+                    "wpid": "GJY_FDC",
+                    "wpname": "高家堰风电场",
+                    "wtid": "GJY01_001",
+                    "wtname": "#01",
+                    "begindate": 1661476154000,
+                    "enddate": 1661562554000,
+                    "faulttype": "变频器",
+                    "faultphenomenon": "FDDF",
+                    "defecteliminating": "DFDDF",
+                    "processingresults": "DFFDF",
+                    "powerloss": 2.2,
+                    "faultduration": 24.0,
+                    "impactcapacity": 48000.0,
+                    "type": "DF"
+                },
+            ],
+            resultsList: [
+                {
+                    name: '已处理'
+                },
+                {
+                    name: '未处理'
+                }
+            ],
+            typesList: [
+                {
+                    name: '内报'
+                },
+                {
+                    name: '外报'
+                }
+            ],
+            dialogVisible: false,
+            sendData: {
+                begindate: '',
+                enddate: '',
+                faulttype: '',
+                faultphenomenon: '',
+                defecteliminating: '',
+                processingresults: '',
+                powerloss: '',
+                type: '',
+            },
+            isEdit: false,
+        };
+    },
+    created() {
+        let date = new Date();
+        this.timeValue[0] = new Date(new Date(new Date().toLocaleDateString()).getTime());
+        this.timeValue[1] = date.getTime();
+        this.getStation()
+    },
+    methods: {
+        getStation() {
+            api.getStation().then(res => {
+                if (res.data) {
+                    let arr = [
+                        {
+                            id: '',
+                            aname: '全部'
+                        }
+                    ]
+                    this.stationList = [ ...arr , ...res.data.data]
+                    console.log(this.stationList);
+                    this.getGroupList(res.data.data[0].code)
+                    this.selectValue = this.stationList[0].id
+                    this.getDatas()
+                }
+            })
+        },
+        getGroupList(groupId) {
+            api.getGroupList({
+                wpid: groupId
+            }).then(res => {
+                this.groupList = res.data.data
+            })
+        },
+        handleChange() {
+            this.getGroupList(this.selectValue)
+        },
+        getDatas() {
+            api.faultrecord({
+                wpid: this.selectValue,
+                wtid: this.groupId,
+                begin: new Date(this.timeValue[0]).getTime(),
+                end: new Date(this.timeValue[1]).getTime(),
+                faulttype: this.typeStatus,
+            }).then(res => {
+                if (res.data) {
+                    res.data.data.forEach(item => {
+                        item.showbegindate = dayjs(item.begindate).format("YYYY-MM-DD HH:mm:ss")
+                        item.showenddate = dayjs(item.enddate).format("YYYY-MM-DD HH:mm:ss")
+                    })
+                    this.tableList = res.data.data
+                }
+            })
+        },
+        add() {
+            if (this.groupId) {
+                this.sendData = {
+                    begindate: '',
+                    enddate: '',
+                    faulttype: '',
+                    faultphenomenon: '',
+                    defecteliminating: '',
+                    processingresults: '',
+                    powerloss: '',
+                    type: '',
+                }
+                this.dialogVisible = true
+                this.isEdit = false
+            } else {
+                this.$message({
+                    message: '请选择风机',
+                    type: 'warning'
+                });
+            }
+
+        },
+        sunmit() {
+            if (this.isEdit) {
+                this.sendData.begindate = new Date(this.sendData.begindate).getTime()
+                this.sendData.enddate = new Date(this.sendData.enddate).getTime()
+                let pairs = this.sendData
+                api.faultrecordEdit(pairs).then(res => {
+                    if (res.data) {
+                        this.$message({
+                            type: 'success',
+                            message: '修改成功!'
+                        });
+                        this.dialogVisible = false
+                        this.getDatas()
+                    }
+                })
+            } else {
+                this.sendData.wtid = this.groupId
+                this.sendData.begindate = new Date(this.sendData.begindate).getTime()
+                this.sendData.enddate = new Date(this.sendData.enddate).getTime()
+                let pairs = this.sendData
+                api.faultrecordAdd(pairs).then(res => {
+                    if (res.data) {
+                        this.$message({
+                            type: 'success',
+                            message: '添加成功!'
+                        });
+                        this.dialogVisible = false
+                        this.getDatas()
+                    }
+                })
+            }
+        },
+        handleEdit(val) {
+            this.isEdit = true
+            this.sendData = val
+            this.dialogVisible = true
+
+        },
+        handleDelete(val) {
+            this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                api.faultrecordDel({
+                    id: val.id
+                }).then(res => {
+                    if (res.data) {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.getDatas()
+                    }
+                })
+
+            }).catch(() => {
+                this.$message({
+                    type: 'info',
+                    message: '已取消删除'
+                });
+            });
+        },
+        exportExcel() {
+            // 数据源
+            let data = [];
+            this.tableList.forEach((item) => {
+                let values = {
+                    期次: item.projectname,
+                    场站名称: item.wpname,
+                    风机名称: item.wtname,
+                    开始时间: item.showbegindate,
+                    结束时间: item.showenddate,
+                    故障分类: item.faulttype,
+                    故障现象: item.faultphenomenon,
+                    消缺工艺: item.defecteliminating,
+                    处理结果: item.processingresults,
+                    损失电量: item.powerloss,
+                    故障时长: item.faultduration,
+                    时长影响容量: item.impactcapacity,
+                    内报外报: item.type,
+                };
+                data.push(values);
+            });
+            // 下载的路径
+            let fileName = `故障录入.xlsx`;
+            let filePath = fileName;
+            // 新建workbook
+            const wb = XLSX.utils.book_new();
+            // 新建worksheet,并载入数据
+            const ws = XLSX.utils.json_to_sheet(data);
+            // 设置每列的列宽,10代表10个字符,注意中文占2个字符
+            ws["!cols"] = [{ wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 25 }, { wch: 25 },];
+            // 生成xlsx文件(workbook,worksheet数据,sheet命名)
+            XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
+
+            // 写文件(workbook,xlsx文件路径+文件名)
+            XLSX.writeFile(wb, filePath);
+        },
+    },
+}
+</script>
+<style lang="less" scoped>
+.title-list {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-top: 10px;
+
+    .search {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .date {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .query-item {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .lable {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .button {
+        width: 80px;
+        height: 40px;
+        margin-left: 30px;
+    }
+}
+
+.table-list {
+    min-height: 40vh;
+}
+
+.lists {
+    width: 90%;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-between;
+    margin: 0 5% 20px 5%;
+}
+
+.rows {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+
+    .rows-name {
+        width: 100px;
+    }
+
+    .rows-input {
+        width: 400px;
+    }
+
+    .rows-inputs {
+        width: 220px;
+    }
+}
+
+.submit {
+    position: absolute;
+    right: 20px;
+    bottom: 20px;
+}
+</style>

+ 512 - 0
src/views/entry/maintain.vue

@@ -0,0 +1,512 @@
+<template>
+    <div>
+        <div class="title-list">
+            <div class="search">
+                <div class="date">风场:</div>
+                <el-select class="inputs" v-model="selectValue" placeholder="请选择" @change="handleChange()">
+                    <el-option v-for="item in stationList" :key="item.aname" :label="item.aname" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="search">
+                <div class="date">机组:</div>
+                <el-select class="inputs" clearable v-model="groupId" placeholder="请选择">
+                    <el-option v-for="item in groupList" :key="item.code" :label="item.code" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="query-item">
+                <div class="lable">开始日期:</div>
+                <div class="search-input">
+                    <el-date-picker v-model="timeValue" type="datetimerange" range-separator="至"
+                        start-placeholder="开始日期" end-placeholder="结束日期">
+                    </el-date-picker>
+                </div>
+            </div>
+            <div class="query-actions">
+                <button class="button" @click="getDatas">查询</button>
+                <button class="button" @click="add">新增</button>
+                <button class="button" @click="exportExcel">导出</button>
+            </div>
+        </div>
+        <div>
+            <el-table height="90vh" ref="multipleTable" empty-text="暂无数据" :data="tableList" stripe
+                style="width: 100%; margin-bottom: 10px">
+                <el-table-column prop="projectname" label="期次" align="center" width="220" sortable></el-table-column>
+                <el-table-column label="场站名称" prop="wpname" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="风机名称" prop="wtname" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="开始时间" prop="showbegindate" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="结束时间" prop="showenddate" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="维护内容" prop="defecteliminating" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="损失电量" prop="powerloss" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="故障时长" prop="faultduration" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="时长影响容量" prop="impactcapacity" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="内报/外报" prop="type" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="操作" align="center">
+                    <template #default="scope">
+                        <el-button type="text" style="color: #597ef7" @click="handleEdit(scope.row)">编辑</el-button>
+                        <el-button type="text" style="color: #b3bdc0" @click="handleDelete(scope.row)">删除</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+
+        <el-dialog v-model="dialogVisible" title="逆变器详情" width="45%" top="10vh" :show-close="true">
+            <div class="table-list">
+                <div class="lists">
+                    <div class="rows">
+                        <div class="rows-name">开始时间:</div>
+                        <el-date-picker v-model="sendData.begindate" type="datetime" placeholder="选择开始时间">
+                        </el-date-picker>
+                    </div>
+                    <div class="rows">
+                        <div class="rows-name">结束时间:</div>
+                        <el-date-picker v-model="sendData.enddate" type="datetime" placeholder="选择结束时间">
+                        </el-date-picker>
+                    </div>
+                </div>
+                <div class="lists">
+                    <div class="rows">
+                        <div class="rows-name">维护内容:</div>
+                        <el-input type="textarea" class="rows-input" v-model="sendData.defecteliminating"
+                            placeholder="请输入维护内容"></el-input>
+                    </div>
+                </div>
+                <div class="lists" style="margin-bottom: 40px">
+                    <div class="rows">
+                        <div class="rows-name">损失电量:</div>
+                        <el-input class="rows-inputs" v-model="sendData.powerloss" placeholder="请输入损失电量"></el-input>
+                    </div>
+                    <div class="rows">
+                        <div class="rows-name">内报/外报:</div>
+                        <el-select class="inputs" clearable v-model="sendData.type" placeholder="请选择">
+                            <el-option v-for="item in typesList" :key="item.name" :label="item.name" :value="item.name">
+                            </el-option>
+                        </el-select>
+                    </div>
+                </div>
+            </div>
+            <div class="submit">
+                <el-button type="primary" plain @click="sunmit">提交</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+<script>
+import api from "api/index";
+import dayjs from "dayjs";
+import XLSX from "xlsx";
+export default {
+    data() {
+        return {
+            timeValue: [],
+            groupId: '',
+            groupList: [
+            ],
+            stationList: [
+            {
+            "id":"WNS_FDC",
+            "code":"WNS_FDC",
+            "name":"太旗卧牛山风电场",
+            "address":"太旗卧牛山风电场",
+            "telephone":null,
+            "capacity":148.5,
+            "capacityunit":"MW",
+            "quantity":99,
+            "aname":"太旗卧牛山",
+            "longitude":1000,
+            "latitude":1000,
+            "photo":null,
+            "companyid":"1",
+            "systemmanufact":null,
+            "headfarm":null,
+            "headfarmphone":null,
+            "model":"UP77-1500/UP77-1500-1/UP77-1500-2",
+            "ordernum":1,
+            "altitude":1000,
+            "height":null
+        },
+        {
+            "id":"YY_FDC",
+            "code":"YY_FDC",
+            "name":"右玉高家堡风电场  ",
+            "address":"右玉高家堡风电场  ",
+            "telephone":null,
+            "capacity":198,
+            "capacityunit":"MW",
+            "quantity":132,
+            "aname":"右玉高家堡",
+            "longitude":1000,
+            "latitude":1000,
+            "photo":null,
+            "companyid":"1",
+            "systemmanufact":null,
+            "headfarm":null,
+            "headfarmphone":null,
+            "model":"UP82-1500/UP82-1500-1/UP86-1500/UP86-1500-1/UP86-1500-2/UP86-1500-3/UP86-1500-4/MY-1.5se",
+            "ordernum":2,
+            "altitude":1000,
+            "height":null
+        },
+        {
+            "id":"PL_FDC",
+            "code":"PL_FDC",
+            "name":"平鲁虎头山风电场  ",
+            "address":"平鲁虎头山风电场  ",
+            "telephone":null,
+            "capacity":223.5,
+            "capacityunit":"MW",
+            "quantity":110,
+            "aname":"平鲁虎头山",
+            "longitude":1000,
+            "latitude":1000,
+            "photo":null,
+            "companyid":"1",
+            "systemmanufact":null,
+            "headfarm":null,
+            "headfarmphone":null,
+            "model":"GW77-1500/GW82-1500/UP3000-120/GW109-2500",
+            "ordernum":3,
+            "altitude":1000,
+            "height":null
+        },
+            ],
+            defaultProps: {
+                children: "data",
+                label: 'code',
+                value: 'id',
+            },
+            selectValue: '',
+            typeList: [
+                {
+                    name: '变频器',
+                },
+                {
+                    name: '发电机',
+                },
+                {
+                    name: '齿轮箱',
+                },
+                {
+                    name: '箱变',
+                },
+                {
+                    name: '偏航系统',
+                },
+                {
+                    name: '液压站',
+                },
+                {
+                    name: '电网',
+                },
+                {
+                    name: '风速风向',
+                },
+                {
+                    name: '主轴',
+                },
+                {
+                    name: '变桨系统',
+                },
+                {
+                    name: '安全链',
+                },
+                {
+                    name: '机舱柜',
+                },
+                {
+                    name: '塔底柜',
+                },
+                {
+                    name: '塔筒',
+                },
+                {
+                    name: '机舱',
+                },
+                {
+                    name: '其他',
+                },
+            ],
+            tableList: [
+            ],
+            resultsList: [
+                {
+                    name: '已处理'
+                },
+                {
+                    name: '未处理'
+                }
+            ],
+            typesList: [
+                {
+                    name: '内报'
+                },
+                {
+                    name: '外报'
+                }
+            ],
+            dialogVisible: false,
+            sendData: {
+                begindate: '',
+                enddate: '',
+                faultphenomenon: '',
+                defecteliminating: '',
+                processingresults: '',
+                powerloss: '',
+                type: '',
+            },
+            isEdit: false,
+        };
+    },
+    created() {
+        let date = new Date();
+        this.timeValue[0] = new Date(new Date(new Date().toLocaleDateString()).getTime());
+        this.timeValue[1] = date.getTime();
+        this.getStation()
+    },
+    methods: {
+        getStation() {
+            api.getStation().then(res => {
+                if (res.data) {
+                    let arr = [
+                        {
+                            id: "",
+                            aname: '全部',
+                            code: "",
+                        }
+                    ]
+                    this.stationList = [ ...arr , ...res.data.data]
+                    console.log(this.stationList);
+                    this.getGroupList(this.stationList[0].code)
+                    this.selectValue = this.stationList[0].id
+                    this.getDatas()
+                }
+            })
+        },
+        getGroupList(groupId) {
+            api.getGroupList({
+                wpid: groupId
+            }).then(res => {
+                this.groupList = res.data.data
+            })
+        },
+
+        handleChange() {
+            this.getGroupList(this.selectValue)
+        },
+        getDatas() {
+            api.mainrecord({
+                wpid: this.selectValue,
+                wtid: this.groupId,
+                begin: new Date(this.timeValue[0]).getTime(),
+                end: new Date(this.timeValue[1]).getTime(),
+            }).then(res => {
+                if (res.data) {
+                    res.data.data.forEach(item => {
+                        item.showbegindate = dayjs(item.begindate).format("YYYY-MM-DD HH:mm:ss")
+                        item.showenddate = dayjs(item.enddate).format("YYYY-MM-DD HH:mm:ss")
+                    })
+                    this.tableList = res.data.data
+                }
+            })
+        },
+        add() {
+            if (this.groupId) {
+                this.sendData = {
+                    begindate: '',
+                    enddate: '',
+                    defecteliminating: '',
+                    powerloss: '',
+                    type: '',
+                }
+                this.dialogVisible = true
+                this.isEdit = false
+            } else {
+                this.$message({
+                    message: '请选择风机',
+                    type: 'warning'
+                });
+            }
+        },
+        sunmit() {
+            if (this.isEdit) {
+                this.sendData.begindate = new Date(this.sendData.begindate).getTime()
+                this.sendData.enddate = new Date(this.sendData.enddate).getTime()
+                let pairs = this.sendData
+                api.mainrecordEdit(pairs).then(res => {
+                    if (res.data) {
+                        this.$message({
+                            type: 'success',
+                            message: '修改成功!'
+                        });
+                        this.dialogVisible = false
+                        this.getDatas()
+                    }
+                })
+            } else {
+                this.sendData.wtid = this.groupId
+                this.sendData.begindate = new Date(this.sendData.begindate).getTime()
+                this.sendData.enddate = new Date(this.sendData.enddate).getTime()
+                let pairs = this.sendData
+                api.mainrecordAdd(pairs).then(res => {
+                    if (res.data) {
+                        this.$message({
+                            type: 'success',
+                            message: '添加成功!'
+                        });
+                        this.dialogVisible = false
+                        this.getDatas()
+                    }
+                })
+            }
+        },
+        handleEdit(val) {
+            this.isEdit = true
+                this.sendData = val
+                this.dialogVisible = true
+        },
+        handleDelete(val) {
+            this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                api.mainrecordDel({
+                    id: val.id
+                }).then(res => {
+                    if (res.data) {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.getDatas()
+                    }
+                })
+
+            }).catch(() => {
+                this.$message({
+                    type: 'info',
+                    message: '已取消删除'
+                });
+            });
+        },
+        exportExcel() {
+            // 数据源
+            let data = [];
+            this.tableList.forEach((item) => {
+                let values = {
+                    期次: item.projectname,
+                    场站名称: item.wpname,
+                    风机名称: item.wtname,
+                    开始时间: item.showbegindate,
+                    结束时间: item.showenddate,
+                    维护内容: item.defecteliminating,
+                    损失电量: item.powerloss,
+                    故障时长: item.faultduration,
+                    时长影响容量: item.impactcapacity,
+                    内报外报: item.type,
+                };
+                data.push(values);
+            });
+            // 下载的路径
+            let fileName = `维护录入.xlsx`;
+            let filePath = fileName;
+            // 新建workbook
+            const wb = XLSX.utils.book_new();
+            // 新建worksheet,并载入数据
+            const ws = XLSX.utils.json_to_sheet(data);
+            // 设置每列的列宽,10代表10个字符,注意中文占2个字符
+            ws["!cols"] = [{ wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 25 }, { wch: 25 },];
+            // 生成xlsx文件(workbook,worksheet数据,sheet命名)
+            XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
+
+            // 写文件(workbook,xlsx文件路径+文件名)
+            XLSX.writeFile(wb, filePath);
+        },
+    },
+}
+</script>
+<style lang="less" scoped>
+.title-list {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-top: 10px;
+
+    .search {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .date {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .query-item {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .lable {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .button {
+        width: 80px;
+        height: 40px;
+        margin-left: 30px;
+    }
+}
+
+.table-list {
+    min-height: 40vh;
+}
+
+.lists {
+    width: 90%;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-between;
+    margin: 0 5% 20px 5%;
+}
+
+.rows {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+
+    .rows-name {
+        width: 100px;
+    }
+
+    .rows-input {
+        width: 400px;
+    }
+
+    .rows-inputs {
+        width: 220px;
+    }
+}
+
+.submit {
+    position: absolute;
+    right: 20px;
+    bottom: 20px;
+}
+</style>

+ 42 - 0
src/views/homePage/detials.vue

@@ -0,0 +1,42 @@
+<template>
+  <el-dialog
+    width="75%"
+    @opened="opened()"
+    @closed="closed()"
+    :show-close="true"
+    class="my-info-dialog"
+  >
+    <template #title>
+      <div style="margin-top: -10px; color: #000000; font-size: 18px">
+        {{ names }}
+      </div>
+    </template>
+    <div class="bodys">
+        <EchartsLine id="echarts" width="100%" height="65vh" :flag="true" :dataList="dataList"></EchartsLine>
+    </div>
+  </el-dialog>
+</template>
+<script>
+import EchartsLine from "@/components/echarts/echartsLine.vue";
+export default {
+    components: {
+    EchartsLine,
+  },
+  props: {
+      dataList: {
+      type: Array,
+      required: [],
+    },
+    names: Object,
+  },
+  methods: {
+    opened() {},
+    closed() {},
+  },
+};
+</script>
+<style lang="less" scoped>
+.bodys {
+  height: 70vh;
+}
+</style>

+ 774 - 0
src/views/homePage/index.vue

@@ -0,0 +1,774 @@
+<template>
+  <div class="bodys">
+    <div class="model">
+      <div class="staions">
+        <div class="staionsName">太旗卧牛山</div>
+      </div>
+      <div class="title">
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风速:</div>
+            <div class="value">{{ titleList.WNS_FDC_FSHH01 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风速:</div>
+            <div class="value">{{ titleList.WNS_FDC_FSHH02 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风速:</div>
+            <div class="value">{{ titleList.WNS_FDC_FSHH03 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风速:</div>
+            <div class="value">{{ titleList.WNS_FDC_FSHH04 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风向:</div>
+            <div class="value">{{ titleList.WNS_FDC_FDFX01 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风向:</div>
+            <div class="value">{{ titleList.WNS_FDC_FDFX02 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风向:</div>
+            <div class="value">{{ titleList.WNS_FDC_FSDFX03 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风向:</div>
+            <div class="value">{{ titleList.WNS_FDC_FDFX04 }}</div>
+            <div class="units">°</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule">
+          <div>
+          <div class="content">
+            <div>第一层温度:</div>
+            <div class="value">{{ titleList.WNS_FDC_FTEMF01 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层湿度:</div>
+            <div class="value">{{ titleList.WNS_FDC_FTEMF02 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层压力:</div>
+            <div class="value">{{ titleList.WNS_FDC_FSTR }}</div>
+            <div class="units"></div>
+          </div>
+          </div>
+        </div>
+      </div>
+      <div style="margin-left:20px;">
+        <EchartsLine
+          id="WNSecharts"
+          :dataList="showData.WNS_FDC"
+          width="100%"
+          height="400px"
+          @click="handleClick('WNS_FDC','太旗卧牛山')"
+        ></EchartsLine>
+      </div>
+    </div>
+
+    <div class="model">
+      <div class="staions">
+        <div class="staionsName">右玉高家堡</div>
+      </div>
+      <div class="title">
+        <div class="titleMoule1">
+          <div>
+            <div class="content">
+                <div>第一层平均风速:</div>
+                <div class="value">{{ titleList.YY_FDC_FSHH01 }}</div>
+                <div class="units">M/S</div>
+            </div>
+            <div class="content">
+                <div>第二层平均风速:</div>
+                <div class="value">{{ titleList.YY_FDC_FSHH02 }}</div>
+                <div class="units">M/S</div>
+            </div>
+            <div class="content">
+                <div>第三层平均风速:</div>
+                <div class="value">{{ titleList.YY_FDC_FSHH03 }}</div>
+                <div class="units">M/S</div>
+            </div>
+            <div class="content">
+                <div>第四层平均风速:</div>
+                <div class="value">{{ titleList.YY_FDC_FSHH04 }}</div>
+                <div class="units">M/S</div>
+            </div>
+          </div>
+        </div>
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风向:</div>
+            <div class="value">{{ titleList.YY_FDC_FDFX01 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风向:</div>
+            <div class="value">{{ titleList.YY_FDC_FDFX02 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风向:</div>
+            <div class="value">{{ titleList.YY_FDC_FSDFX03 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风向:</div>
+            <div class="value">{{ titleList.YY_FDC_FDFX04 }}</div>
+            <div class="units">°</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule">
+          <div>
+          <div class="content">
+            <div>第一层温度:</div>
+            <div class="value">{{ titleList.YY_FDC_FTEMF01 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层湿度:</div>
+            <div class="value">{{ titleList.YY_FDC_FTEMF02 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层压力:</div>
+            <div class="value">{{ titleList.YY_FDC_FSTR }}</div>
+            <div class="units"></div>
+          </div>
+          </div>
+        </div>
+      </div>
+      <div style="margin-left:20px;">
+        <EchartsLine id="YYecharts" width="100%" height="400px" :dataList="showData.YY_FDC" @click="handleClick('YY_FDC','右玉高家堡')"></EchartsLine>
+      </div>
+    </div>
+
+    <div class="model">
+      <div class="staions">
+        <div class="staionsName">平鲁虎头山</div>
+      </div>
+      <div class="title">
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风速:</div>
+            <div class="value">{{ titleList.PL_FDC_FSHH01 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风速:</div>
+            <div class="value">{{ titleList.PL_FDC_FSHH02 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风速:</div>
+            <div class="value">{{ titleList.PL_FDC_FSHH03 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风速:</div>
+            <div class="value">{{ titleList.PL_FDC_FSHH04 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风向:</div>
+            <div class="value">{{ titleList.PL_FDC_FDFX01 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风向:</div>
+            <div class="value">{{ titleList.PL_FDC_FDFX02 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风向:</div>
+            <div class="value">{{ titleList.PL_FDC_FSDFX03 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风向:</div>
+            <div class="value">{{ titleList.PL_FDC_FDFX04 }}</div>
+            <div class="units">°</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule">
+          <div>
+          <div class="content">
+            <div>第一层温度:</div>
+            <div class="value">{{ titleList.PL_FDC_FTEMF01 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层湿度:</div>
+            <div class="value">{{ titleList.PL_FDC_FTEMF02 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层压力:</div>
+            <div class="value">{{ titleList.PL_FDC_FSTR }}</div>
+            <div class="units"></div>
+          </div>
+          </div>
+        </div>
+      </div>
+      <div style="margin-left:20px;">
+        <EchartsLine id="PLecharts" width="100%" height="400px" :dataList="showData.PL_FDC" @click="handleClick('PL_FDC','平鲁虎头山')"></EchartsLine>
+      </div>
+    </div>
+
+    <div class="model">
+      <div class="staions">
+        <div class="staionsName">广灵劲风</div>
+      </div>
+      <div class="title">
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风速:</div>
+            <div class="value">{{ titleList.GL_FDC_FSHH01 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风速:</div>
+            <div class="value">{{ titleList.GL_FDC_FSHH02 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风速:</div>
+            <div class="value">{{ titleList.GL_FDC_FSHH03 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风速:</div>
+            <div class="value">{{ titleList.GL_FDC_FSHH04 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风向:</div>
+            <div class="value">{{ titleList.GL_FDC_FDFX01 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风向:</div>
+            <div class="value">{{ titleList.GL_FDC_FDFX02 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风向:</div>
+            <div class="value">{{ titleList.GL_FDC_FSDFX03 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风向:</div>
+            <div class="value">{{ titleList.GL_FDC_FDFX04 }}</div>
+            <div class="units">°</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule">
+          <div>
+          <div class="content">
+            <div>第一层温度:</div>
+            <div class="value">{{ titleList.GL_FDC_FTEMF01 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层湿度:</div>
+            <div class="value">{{ titleList.GL_FDC_FTEMF02 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层压力:</div>
+            <div class="value">{{ titleList.GL_FDC_FSTR }}</div>
+            <div class="units"></div>
+          </div>
+          </div>
+        </div>
+      </div>
+      <div style="margin-left:20px;">
+        <EchartsLine id="GLecharts" width="100%" height="400px" :dataList="showData.GL_FDC" @click="handleClick('GL_FDC','广灵劲风')"></EchartsLine>
+      </div>
+    </div>
+
+    <div class="model">
+      <div class="staions">
+        <div class="staionsName">浑源峰岳</div>
+      </div>
+      <div class="title">
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风速:</div>
+            <div class="value">{{ titleList.HY_FDC_FSHH01 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风速:</div>
+            <div class="value">{{ titleList.HY_FDC_FSHH02 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风速:</div>
+            <div class="value">{{ titleList.HY_FDC_FSHH03 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风速:</div>
+            <div class="value">{{ titleList.HY_FDC_FSHH04 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风向:</div>
+            <div class="value">{{ titleList.HY_FDC_FDFX01 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风向:</div>
+            <div class="value">{{ titleList.HY_FDC_FDFX02 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风向:</div>
+            <div class="value">{{ titleList.HY_FDC_FSDFX03 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风向:</div>
+            <div class="value">{{ titleList.HY_FDC_FDFX04 }}</div>
+            <div class="units">°</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule">
+          <div>
+          <div class="content">
+            <div>第一层温度:</div>
+            <div class="value">{{ titleList.HY_FDC_FTEMF01 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层湿度:</div>
+            <div class="value">{{ titleList.HY_FDC_FTEMF02 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层压力:</div>
+            <div class="value">{{ titleList.HY_FDC_FSTR }}</div>
+            <div class="units"></div>
+          </div>
+          </div>
+        </div>
+      </div>
+      <div style="margin-left:20px;">
+        <EchartsLine id="HYecharts" width="100%" height="400px" :dataList="showData.HY_FDC" @click="handleClick('HY_FDC','浑源峰岳')"></EchartsLine>
+      </div>
+    </div>
+
+    <div class="model">
+      <div class="staions">
+        <div class="staionsName">方山宝塔山</div>
+      </div>
+      <div class="title">
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风速:</div>
+            <div class="value">{{ titleList.FS_FDC_FSHH01 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风速:</div>
+            <div class="value">{{ titleList.FS_FDC_FSHH02 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风速:</div>
+            <div class="value">{{ titleList.FS_FDC_FSHH03 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风速:</div>
+            <div class="value">{{ titleList.FS_FDC_FSHH04 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风向:</div>
+            <div class="value">{{ titleList.FS_FDC_FDFX01 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风向:</div>
+            <div class="value">{{ titleList.FS_FDC_FDFX02 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风向:</div>
+            <div class="value">{{ titleList.FS_FDC_FSDFX03 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风向:</div>
+            <div class="value">{{ titleList.FS_FDC_FDFX04 }}</div>
+            <div class="units">°</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule">
+          <div>
+          <div class="content">
+            <div>第一层温度:</div>
+            <div class="value">{{ titleList.FS_FDC_FTEMF01 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层湿度:</div>
+            <div class="value">{{ titleList.FS_FDC_FTEMF02 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层压力:</div>
+            <div class="value">{{ titleList.FS_FDC_FSTR }}</div>
+            <div class="units"></div>
+          </div>
+          </div>
+        </div>
+      </div>
+      <div style="margin-left:20px;">
+        <EchartsLine id="FSecharts" width="100%" height="400px" :dataList="showData.FS_FDC" @click="handleClick('FS_FDC','方山宝塔山')"></EchartsLine>
+      </div>
+    </div>
+
+    <div class="model">
+      <div class="staions">
+        <div class="staionsName">阳高采凉山</div>
+      </div>
+      <div class="title">
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风速:</div>
+            <div class="value">{{ titleList.YG_FDC_FSHH01 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风速:</div>
+            <div class="value">{{ titleList.YG_FDC_FSHH02 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风速:</div>
+            <div class="value">{{ titleList.YG_FDC_FSHH03 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风速:</div>
+            <div class="value">{{ titleList.YG_FDC_FSHH04 }}</div>
+            <div class="units">M/S</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule1">
+          <div>
+          <div class="content">
+            <div>第一层平均风向:</div>
+            <div class="value">{{ titleList.YG_FDC_FDFX01 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第二层平均风向:</div>
+            <div class="value">{{ titleList.YG_FDC_FDFX02 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第三层平均风向:</div>
+            <div class="value">{{ titleList.YG_FDC_FSDFX03 }}</div>
+            <div class="units">°</div>
+          </div>
+          <div class="content">
+            <div>第四层平均风向:</div>
+            <div class="value">{{ titleList.YG_FDC_FDFX04 }}</div>
+            <div class="units">°</div>
+          </div>
+          </div>
+        </div>
+
+        <div class="titleMoule">
+          <div>
+          <div class="content">
+            <div>第一层温度:</div>
+            <div class="value">{{ titleList.YG_FDC_FTEMF01 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层湿度:</div>
+            <div class="value">{{ titleList.YG_FDC_FTEMF02 }}</div>
+            <div class="units">℃</div>
+          </div>
+          <div class="content">
+            <div>第一层压力:</div>
+            <div class="value">{{ titleList.YG_FDC_FSTR }}</div>
+            <div class="units"></div>
+          </div>
+          </div>
+        </div>
+      </div>
+      <div style="margin-left:20px;">
+        <EchartsLine id="YGecharts" width="100%" height="400px" :dataList="showData.YG_FDC" @click="handleClick('YG_FDC','阳高采凉山')"></EchartsLine>
+      </div>
+    </div>
+  </div>
+  <Detials :names="names" :dataList="detialsList" v-model="dialogVisible"></Detials>
+</template>
+<script>
+import EchartsLine from "@/components/echarts/echartsLine.vue";
+import Detials from "./detials.vue";
+
+import api from "api/index";
+export default {
+  components: {
+    EchartsLine,
+    Detials,
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      detialsList: [],
+      names: "",
+      titleList: {
+        GL_FDC_FDFX01: 0,
+        GL_FDC_FDFX02: 0,
+        FS_FDC_FSDFX03: 0,
+        WNS_FDC_FSDFX03: 0,
+        GL_FDC_FDFX04: 0,
+        YG_FDC_FSDFX03: 254.2,
+        HY_FDC_FSDFX03: 0,
+        GL_FDC_FSHH01: 0,
+        GL_FDC_FSHH02: 0,
+        HY_FDC_FSTR: 0,
+        GL_FDC_FSHH03: 0,
+        GL_FDC_FSHH04: 0,
+        YG_FDC_FSHH01: 5.16,
+        YG_FDC_FSHH02: 5.64,
+        YG_FDC_FSHH03: 5.81,
+        YG_FDC_FSHH04: 6.09,
+        WNS_FDC_FDFX04: 0,
+        FS_FDC_FSHH01: 0,
+        GL_FDC_FTEMF01: 0,
+        FS_FDC_FSHH02: 0,
+        GL_FDC_FTEMF02: 0,
+        YY_FDC_FTEMF01: 0,
+        YY_FDC_FTEMF02: 0,
+        FS_FDC_FSHH03: 0,
+        FS_FDC_FSHH04: 0,
+        PL_FDC_FTEMF01: 0,
+        HY_FDC_FSHH01: 0,
+        PL_FDC_FSDFX03: 0,
+        PL_FDC_FTEMF02: 0,
+        HY_FDC_FSHH02: 0,
+        WNS_FDC_FDFX01: 0,
+        YG_FDC_FDFX01: 261.8,
+        WNS_FDC_FDFX02: 0,
+        YG_FDC_FDFX02: 244.3,
+        HY_FDC_FSHH03: 0,
+        HY_FDC_FSHH04: 0,
+        YG_FDC_FDFX04: 264.6,
+        PL_FDC_FSTR: 0,
+        FS_FDC_FDFX04: 0,
+        FS_FDC_FDFX02: 0,
+        WNS_FDC_FSHH01: 0,
+        FS_FDC_FDFX01: 0,
+        WNS_FDC_FSHH04: 0,
+        WNS_FDC_FSHH02: 0,
+        WNS_FDC_FSHH03: 0,
+        HY_FDC_FDFX04: 0,
+        HY_FDC_FDFX02: 0,
+        GL_FDC_FSTR: 0,
+        GL_FDC_FSDFX03: 0,
+        HY_FDC_FDFX01: 0,
+        YY_FDC_FSDFX03: 0,
+        YY_FDC_FSTR: 0,
+        FS_FDC_FSTR: 0,
+        WNS_FDC_FSTR: 0,
+        YG_FDC_FSTR: 862,
+        YY_FDC_FDFX02: 0,
+        YY_FDC_FDFX01: 0,
+        YY_FDC_FDFX04: 0,
+        FS_FDC_FTEMF02: 0,
+        PL_FDC_FDFX02: 0,
+        FS_FDC_FTEMF01: 0,
+        PL_FDC_FDFX01: 0,
+        PL_FDC_FDFX04: 0,
+        HY_FDC_FTEMF01: 0,
+        YY_FDC_FSHH01: 0,
+        HY_FDC_FTEMF02: 0,
+        PL_FDC_FSHH03: 0,
+        PL_FDC_FSHH02: 0,
+        YG_FDC_FTEMF02: 33.6,
+        PL_FDC_FSHH04: 0,
+        YG_FDC_FTEMF01: -8.03,
+        YY_FDC_FSHH03: 0,
+        YY_FDC_FSHH02: 0,
+        WNS_FDC_FTEMF02: 0,
+        PL_FDC_FSHH01: 0,
+        WNS_FDC_FTEMF01: 0,
+        YY_FDC_FSHH04: 0,
+      },
+      showData: {},
+    };
+  },
+  created() {
+    this.getwindpowerVal();
+    this.getwindpowerLine();
+  },
+  methods: {
+    getwindpowerVal() {
+      api.getwindpowerVal().then((res) => {
+        if (res) {
+          this.titleList = res.data;
+          setTimeout(() => {
+            this.getwindpowerVal();
+          }, 300000);
+        }
+      });
+    },
+    getwindpowerLine() {
+      api.getwindpowerLine().then((res) => {
+        if (res) {
+          this.showData = res.data;
+          setTimeout(() => {
+            this.getwindpowerLine();
+          }, 1800000);
+        }
+      });
+    },
+    handleClick(val, name) {
+      this.detialsList = this.showData[val],
+        (this.names = name),
+        (this.dialogVisible = true);
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+.bodys {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  flex-wrap: wrap;
+  width: 100%;
+  height: 100vh;
+  overflow-y: auto;
+  .staions {
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    .staionsName {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      font-size: 22px;
+      font-weight: bold;
+      margin-left: 10px;
+      margin-top: -23px;
+      border: 1px solid #000000;
+      padding: 10px;
+      background-color: #ffffff;
+    }
+  }
+
+  .model {
+    width: 30%;
+    border: 1px solid #999999;
+    margin: 40px 20px;
+    .title {
+      display: flex;
+      flex-direction: row;
+      justify-content: center;
+      width: 100%;
+
+      .titleMoule {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        margin-top: 20px;
+        width: 31%;
+      }
+      .titleMoule1 {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        margin-top: 20px;
+        width: 40%;
+      }
+      .content {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-bottom: 5px;
+        font-size: 12px;
+        color: #000000;
+
+        .value {
+          min-width: 20px;
+          font-size: 14px;
+          color: #ff2d2d;
+          margin-left: 10px;
+          margin-right: 5px;
+          font-weight: bold;
+        }
+        .units {
+          width: 20px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 399 - 0
src/views/tablePage/index.vue

@@ -0,0 +1,399 @@
+<template>
+    <div>
+        <div class="title-list">
+            <div class="search">
+                <div class="date">风场:</div>
+                <el-select class="inputs" v-model="selectValue" placeholder="请选择">
+                    <el-option v-for="item in stationList" :key="item.name" :label="item.name" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="query-item">
+                <div class="lable">开始日期:</div>
+                <div class="search-input">
+                    <el-date-picker v-model="timeValue" type="daterange" range-separator="至" start-placeholder="开始日期"
+                        end-placeholder="结束日期">
+                    </el-date-picker>
+                </div>
+            </div>
+            <div class="query-actions">
+                <button class="button" @click="getTableData">查询</button>
+                <button class="button" @click="exportExcel">导出</button>
+            </div>
+        </div>
+        <div>
+            <el-table height="90vh" ref="multipleTable" empty-text="暂无数据" :data="tableList" stripe
+                style="width: 100%; margin-bottom: 10px">
+                <el-table-column prop="windturbinename" label="风机" align="center"  width="220"  sortable></el-table-column>
+                <el-table-column label="发电量" align="center" prop="generatingcapacity" sortable>
+                </el-table-column>
+                <el-table-column label="理论发电量" prop="theoreticalcapacity" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="故障损失电量" prop="daynhgzssdl" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="维护损失电量" prop="daynhwhssdl" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="限电损失电量" prop="daynhxdssdl" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="性能损失电量" prop="daynhqfdl" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="受累损失电量" prop="daynhcfdl" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="设备可利用率" prop="availability" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="并网时间" prop="runtime" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="维护时间" prop="maintime" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="故障时间" prop="faulttime" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="停机时间" prop="stoptime" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="风暴时间" prop="stormtime" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="离线时间" prop="offtime" align="center" sortable>
+                </el-table-column>
+            </el-table>
+        </div>
+    </div>
+</template>
+<script>
+import api from "api/index";
+import dayjs from "dayjs";
+import XLSX from "xlsx";
+export default {
+    data() {
+        return {
+            timeValue: [],
+            selectValue: "WNS_FDC",
+            tableList: [
+                {
+                    "id": null,
+                    "windturbineid": "GL01_005",
+                    "windturbinename": "广灵第005台风机",
+                    "windpowerstationid": null,
+                    "generatingcapacity": 9472,
+                    "theoreticalcapacity": 13079.75,
+                    "daynhgzssdl": 0,
+                    "daynhwhssdl": 0,
+                    "daynhxdssdl": 0,
+                    "daynhqfdl": 3607.75,
+                    "daynhcfdl": 0,
+                    "availability": 100,
+                    "powerfactor": null,
+                    "runtime": 14.47,
+                    "maintime": 0,
+                    "faulttime": 0,
+                    "stoptime": 9.53,
+                    "stormtime": 0,
+                    "offtime": 0,
+                    "recorddate": null
+                },
+                {
+                    "id": null,
+                    "windturbineid": "GL01_013",
+                    "windturbinename": "广灵第013台风机",
+                    "windpowerstationid": null,
+                    "generatingcapacity": 2600,
+                    "theoreticalcapacity": 9691.89,
+                    "daynhgzssdl": 0,
+                    "daynhwhssdl": 0,
+                    "daynhxdssdl": 0,
+                    "daynhqfdl": 7091.89,
+                    "daynhcfdl": 0,
+                    "availability": 100,
+                    "powerfactor": null,
+                    "runtime": 11.67,
+                    "maintime": 0,
+                    "faulttime": 0,
+                    "stoptime": 12.33,
+                    "stormtime": 0,
+                    "offtime": 0,
+                    "recorddate": null
+                },
+                {
+                    "id": null,
+                    "windturbineid": "GL01_015",
+                    "windturbinename": "广灵第015台风机",
+                    "windpowerstationid": null,
+                    "generatingcapacity": 6268,
+                    "theoreticalcapacity": 10649.49,
+                    "daynhgzssdl": 0,
+                    "daynhwhssdl": 0,
+                    "daynhxdssdl": 0,
+                    "daynhqfdl": 4381.49,
+                    "daynhcfdl": 0,
+                    "availability": 100,
+                    "powerfactor": null,
+                    "runtime": 13.83,
+                    "maintime": 0,
+                    "faulttime": 0,
+                    "stoptime": 10.17,
+                    "stormtime": 0,
+                    "offtime": 0,
+                    "recorddate": null
+                },
+            ],
+            stationList: [
+                {
+                    "id": "WNS_FDC",
+                    "code": "WNS_FDC",
+                    "name": "太旗卧牛山风电场",
+                    "address": "太旗卧牛山风电场",
+                    "telephone": null,
+                    "capacity": 148.5,
+                    "capacityunit": "MW",
+                    "quantity": 99,
+                    "aname": "卧牛山风电场",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP77-1500/UP77-1500-1/UP77-1500-2",
+                    "ordernum": 1,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "YY_FDC",
+                    "code": "YY_FDC",
+                    "name": "右玉高家堡风电场  ",
+                    "address": "右玉高家堡风电场  ",
+                    "telephone": null,
+                    "capacity": 198,
+                    "capacityunit": "MW",
+                    "quantity": 132,
+                    "aname": "高家堡风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP82-1500/UP82-1500-1/UP86-1500/UP86-1500-1/UP86-1500-2/UP86-1500-3/UP86-1500-4/MY-1.5se",
+                    "ordernum": 2,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "PL_FDC",
+                    "code": "PL_FDC",
+                    "name": "平鲁虎头山风电场  ",
+                    "address": "平鲁虎头山风电场  ",
+                    "telephone": null,
+                    "capacity": 223.5,
+                    "capacityunit": "MW",
+                    "quantity": 110,
+                    "aname": "虎头山风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "GW77-1500/GW82-1500/UP3000-120/GW109-2500",
+                    "ordernum": 3,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "GL_FDC",
+                    "code": "GL_FDC",
+                    "name": "广灵劲风风电场  ",
+                    "address": "广灵劲风风电场  ",
+                    "telephone": null,
+                    "capacity": 48,
+                    "capacityunit": "MW",
+                    "quantity": 24,
+                    "aname": "劲风风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP2000-105s",
+                    "ordernum": 4,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "HY_FDC",
+                    "code": "HY_FDC",
+                    "name": "浑源峰岳风电场 ",
+                    "address": "浑源峰岳风电场 ",
+                    "telephone": null,
+                    "capacity": 149.5,
+                    "capacityunit": "MW",
+                    "quantity": 80,
+                    "aname": "峰岳风电场 ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP82-1500-2/UP86-1500-2/UP2000-96/UP2000-105s",
+                    "ordernum": 5,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "FS_FDC",
+                    "code": "FS_FDC",
+                    "name": "方山宝塔山风电场 ",
+                    "address": "方山宝塔山风电场 ",
+                    "telephone": null,
+                    "capacity": 96,
+                    "capacityunit": "MW",
+                    "quantity": 48,
+                    "aname": "宝塔山风电场 ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP2000-105s/UP2000-96",
+                    "ordernum": 6,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "YG_FDC",
+                    "code": "YG_FDC",
+                    "name": "阳高采凉山风电场",
+                    "address": "阳高采凉山风电场",
+                    "telephone": null,
+                    "capacity": 90,
+                    "capacityunit": "MW",
+                    "quantity": 45,
+                    "aname": "采凉山风电场",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP2000-115s",
+                    "ordernum": 7,
+                    "altitude": 1000,
+                    "height": null
+                }
+            ],
+        };
+    },
+    created() {
+        let date = new Date();
+        this.timeValue[0] = date.getTime() - 86400000;
+        this.timeValue[1] = date.getTime() - 86400000;
+        this.getStation()
+    },
+    methods: {
+        getStation() {
+            api.getStation().then(res => {
+                if (res.data) {
+                    this.stationList = res.data.data
+                    this.getTableData()
+                }
+            })
+        },
+        getTableData() {
+            api.getTableData({
+                wpid: this.selectValue,
+                beginDate: dayjs(this.timeValue[0]).format("YYYY-MM-DD"),
+                endDate: dayjs(this.timeValue[1]).format("YYYY-MM-DD"),
+            }).then(res => {
+                if (res.data) {
+                    this.tableList = res.data.data
+                }
+            })
+        },
+        exportExcel() {
+            // 数据源
+            let data = [];
+            this.tableList.forEach((item) => {
+                let values = {
+                    风机: item.windturbinename,
+                    发电量: item.generatingcapacity,
+                    理论发电量: item.theoreticalcapacity,
+                    故障损失电量: item.daynhgzssdl,
+                    维护损失电量: item.daynhwhssdl,
+                    限电损失电量: item.daynhxdssdl,
+                    性能损失电量: item.daynhqfdl,
+                    受累损失电量: item.daynhcfdl,
+                    设备可利用率: item.availability,
+                    并网时间: item.runtime,
+                    维护时间: item.maintime,
+                    故障时间: item.faulttime,
+                    停机时间: item.stoptime,
+                    风暴时间: item.stormtime,
+                    离线时间: item.offtime,
+                };
+                data.push(values);
+            });
+            // 下载的路径
+            let fileName = `风机运行分析.xlsx`;
+            let filePath = fileName;
+            // 新建workbook
+            const wb = XLSX.utils.book_new();
+            // 新建worksheet,并载入数据
+            const ws = XLSX.utils.json_to_sheet(data);
+            // 设置每列的列宽,10代表10个字符,注意中文占2个字符
+            ws["!cols"] = [{ wch: 20 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }];
+            // 生成xlsx文件(workbook,worksheet数据,sheet命名)
+            XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
+
+            // 写文件(workbook,xlsx文件路径+文件名)
+            XLSX.writeFile(wb, filePath);
+        },
+    },
+}
+</script>
+<style lang="less" scoped>
+.title-list {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-top: 10px;
+
+    .search {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .date {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .query-item {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .lable {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .button {
+        width: 80px;
+        height: 40px;
+        margin-left: 30px;
+    }
+}
+</style>

+ 368 - 0
src/views/tablePage1/index.vue

@@ -0,0 +1,368 @@
+<template>
+    <div>
+        <div class="title-list">
+            <div class="search">
+                <div class="date">风场:</div>
+                <el-select class="inputs" v-model="selectValue" placeholder="请选择">
+                    <el-option v-for="item in stationList" :key="item.name" :label="item.name" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <!-- <div class="query-item">
+                <div class="lable">日期:</div>
+                <div class="search-input">
+                    <el-date-picker v-model="timeValue" type="daterange" range-separator="至" start-placeholder="开始日期"
+                        end-placeholder="结束日期">
+                    </el-date-picker>
+                </div>
+            </div> -->
+            <div class="query-actions">
+                <button class="button" @click="getTableData">查询</button>
+                <button class="button" @click="exportExcel">导出</button>
+            </div>
+        </div>
+        <div>
+            <el-table height="90vh" ref="multipleTable" empty-text="暂无数据" :data="tableList" stripe
+                style="width: 100%; margin-bottom: 10px">
+                <el-table-column prop="windturbineName" label="风机" align="center" width="220" sortable>
+                </el-table-column>
+                <el-table-column label="风向" align="center" prop="windDirection" sortable>
+                </el-table-column>
+                <el-table-column label="风速" prop="speed" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="功率" prop="power" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="功率因数" prop="powerFactor" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="对风角度" prop="oppositeWindAngle" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="功率限定值" prop="powerLimit" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="转速限定值" prop="speedLimit" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="状态" prop="status" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="无功功率" prop="reactivePower" align="center" sortable>
+                </el-table-column>
+            </el-table>
+        </div>
+    </div>
+</template>
+<script>
+import api from "api/index";
+import dayjs from "dayjs";
+import XLSX from "xlsx";
+export default {
+    data() {
+        return {
+            timeValue: [],
+            selectValue: "WNS_FDC",
+            tableList: [
+                {
+                    "windturbineId": "GL01_001",
+                    "windturbineName": "广灵第001台风机",
+                    "windDirection": 12.59,
+                    "speed": 5.11,
+                    "power": 684.5,
+                    "powerFactor": 1,
+                    "oppositeWindAngle": null,
+                    "powerLimit": 2050000,
+                    "speedLimit": null,
+                    "status": "并网",
+                    "fault": null,
+                    "reactivePower": -12.8
+                },
+                {
+                    "windturbineId": "GL01_002",
+                    "windturbineName": "广灵第002台风机",
+                    "windDirection": 22.59,
+                    "speed": 15.11,
+                    "power": 1684.5,
+                    "powerFactor": 11,
+                    "oppositeWindAngle": null,
+                    "powerLimit": 12050000,
+                    "speedLimit": null,
+                    "status": "并网",
+                    "fault": null,
+                    "reactivePower": 12.8
+                },
+                {
+                    "windturbineId": "GL01_002",
+                    "windturbineName": "广灵第015台风机",
+                    "windDirection": 22.59,
+                    "speed": 15.11,
+                    "power": 1684.5,
+                    "powerFactor": 11,
+                    "oppositeWindAngle": null,
+                    "powerLimit": 12050000,
+                    "speedLimit": null,
+                    "status": "并网",
+                    "fault": null,
+                    "reactivePower": 12.8
+                },
+            ],
+            stationList: [
+                {
+                    "id": "WNS_FDC",
+                    "code": "WNS_FDC",
+                    "name": "太旗卧牛山风电场",
+                    "address": "太旗卧牛山风电场",
+                    "telephone": null,
+                    "capacity": 148.5,
+                    "capacityunit": "MW",
+                    "quantity": 99,
+                    "aname": "卧牛山风电场",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP77-1500/UP77-1500-1/UP77-1500-2",
+                    "ordernum": 1,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "YY_FDC",
+                    "code": "YY_FDC",
+                    "name": "右玉高家堡风电场  ",
+                    "address": "右玉高家堡风电场  ",
+                    "telephone": null,
+                    "capacity": 198,
+                    "capacityunit": "MW",
+                    "quantity": 132,
+                    "aname": "高家堡风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP82-1500/UP82-1500-1/UP86-1500/UP86-1500-1/UP86-1500-2/UP86-1500-3/UP86-1500-4/MY-1.5se",
+                    "ordernum": 2,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "PL_FDC",
+                    "code": "PL_FDC",
+                    "name": "平鲁虎头山风电场  ",
+                    "address": "平鲁虎头山风电场  ",
+                    "telephone": null,
+                    "capacity": 223.5,
+                    "capacityunit": "MW",
+                    "quantity": 110,
+                    "aname": "虎头山风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "GW77-1500/GW82-1500/UP3000-120/GW109-2500",
+                    "ordernum": 3,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "GL_FDC",
+                    "code": "GL_FDC",
+                    "name": "广灵劲风风电场  ",
+                    "address": "广灵劲风风电场  ",
+                    "telephone": null,
+                    "capacity": 48,
+                    "capacityunit": "MW",
+                    "quantity": 24,
+                    "aname": "劲风风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP2000-105s",
+                    "ordernum": 4,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "HY_FDC",
+                    "code": "HY_FDC",
+                    "name": "浑源峰岳风电场 ",
+                    "address": "浑源峰岳风电场 ",
+                    "telephone": null,
+                    "capacity": 149.5,
+                    "capacityunit": "MW",
+                    "quantity": 80,
+                    "aname": "峰岳风电场 ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP82-1500-2/UP86-1500-2/UP2000-96/UP2000-105s",
+                    "ordernum": 5,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "FS_FDC",
+                    "code": "FS_FDC",
+                    "name": "方山宝塔山风电场 ",
+                    "address": "方山宝塔山风电场 ",
+                    "telephone": null,
+                    "capacity": 96,
+                    "capacityunit": "MW",
+                    "quantity": 48,
+                    "aname": "宝塔山风电场 ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP2000-105s/UP2000-96",
+                    "ordernum": 6,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "YG_FDC",
+                    "code": "YG_FDC",
+                    "name": "阳高采凉山风电场",
+                    "address": "阳高采凉山风电场",
+                    "telephone": null,
+                    "capacity": 90,
+                    "capacityunit": "MW",
+                    "quantity": 45,
+                    "aname": "采凉山风电场",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP2000-115s",
+                    "ordernum": 7,
+                    "altitude": 1000,
+                    "height": null
+                }
+            ],
+            // 定时器
+            timer: "",
+        };
+    },
+    created() {
+        // let date = new Date();
+        // this.timeValue[0] = date.getTime() - 86400000;
+        // this.timeValue[1] = date.getTime() - 86400000;
+        this.getStation()
+        this.timer = setInterval(() => {
+            this.getTableData()
+        }, 3000);
+    },
+    methods: {
+        getStation() {
+            api.getStation().then(res => {
+                if (res.data) {
+                    this.stationList = res.data.data
+                    this.getTableData()
+                }
+            })
+        },
+        getTableData() {
+            api.natureReal({
+                wpid: this.selectValue
+            }).then(res => {
+                if (res.data) {
+                    this.tableList = res.data.data
+                }
+            })
+        },
+        exportExcel() {
+            // 数据源
+            let data = [];
+            this.tableList.forEach((item) => {
+                let values = {
+                    风机: item.windturbineName,
+                    风向: item.windDirection,
+                    风速: item.speed,
+                    功率: item.power,
+                    功率因数: item.powerFactor,
+                    对风角度: item.oppositeWindAngle,
+                    功率限定值: item.powerLimit,
+                    转速限定值: item.speedLimit,
+                    状态: item.status,
+                    无功功率: item.reactivePower,
+                };
+                data.push(values);
+            });
+            // 下载的路径
+            let fileName = `风机性能分析.xlsx`;
+            let filePath = fileName;
+            // 新建workbook
+            const wb = XLSX.utils.book_new();
+            // 新建worksheet,并载入数据
+            const ws = XLSX.utils.json_to_sheet(data);
+            // 设置每列的列宽,10代表10个字符,注意中文占2个字符
+            ws["!cols"] = [{ wch: 20 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }, { wch: 10 }];
+            // 生成xlsx文件(workbook,worksheet数据,sheet命名)
+            XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
+
+            // 写文件(workbook,xlsx文件路径+文件名)
+            XLSX.writeFile(wb, filePath);
+        },
+    },
+    unmounted() {
+        clearInterval(this.timer);
+        this.timer = null;
+    },
+}
+</script>
+<style lang="less" scoped>
+.title-list {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-top: 10px;
+
+    .search {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .date {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .query-item {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .lable {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .button {
+        width: 80px;
+        height: 40px;
+        margin-left: 30px;
+    }
+}
+</style>

+ 375 - 0
src/views/tablePage2/index.vue

@@ -0,0 +1,375 @@
+<template>
+    <div>
+        <div class="title-list">
+            <div class="search">
+                <div class="date">风场:</div>
+                <el-select class="inputs" v-model="selectValue" placeholder="请选择">
+                    <el-option v-for="item in stationList" :key="item.name" :label="item.name" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="search">
+                <div class="date">类型:</div>
+                <el-select class="inputs" clearable v-model="typeStatus" placeholder="请选择">
+                    <el-option v-for="item in typeList" :key="item.name" :label="item.name" :value="item.value">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="query-item">
+                <div class="lable">日期:</div>
+                <div class="search-input">
+                    <el-date-picker v-model="timeValue" type="daterange" range-separator="至" start-placeholder="开始日期"
+                        end-placeholder="结束日期">
+                    </el-date-picker>
+                </div>
+            </div>
+            <div class="query-actions">
+                <button class="button" @click="getTableData">查询</button>
+                <button class="button" @click="exportExcel">导出</button>
+            </div>
+        </div>
+        <div>
+            <el-table height="90vh" ref="multipleTable" empty-text="暂无数据" :data="tableList" stripe
+                style="width: 100%; margin-bottom: 10px">
+                <el-table-column prop="windturbineid" label="风机" align="center"  width="220" sortable></el-table-column>
+                <el-table-column label="停机时间" prop="stoptime" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="恢复时间" prop="starttime" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="停机小时" prop="stophours" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="损失电量" prop="losspower" align="center" sortable>
+                </el-table-column>
+                <el-table-column label="停机类型" prop="stoptypeid" align="center" sortable>
+                </el-table-column>
+            </el-table>
+        </div>
+    </div>
+</template>
+<script>
+import api from "api/index";
+import dayjs from "dayjs";
+import XLSX from "xlsx";
+export default {
+    data() {
+        return {
+            timeValue: [],
+            selectValue: "WNS_FDC",
+            tableList: [
+                {
+                    "id": "4ee7456f-50a1-4452-bf17-c17c899d4013",
+                    "windpowerstationid": "GL_FDC",
+                    "windturbineid": "广灵第012台风机",
+                    "stoptime": "2022-08-03T01:23:55.000+0000",
+                    "starttime": null,
+                    "stophours": null,
+                    "losspower": null,
+                    "stoptypeid": "故障不明确",
+                    "ishandle": null,
+                    "warningid": null,
+                    "projectid": "GL01_GC",
+                    "handleway": null,
+                    "faultview": null,
+                    "statuscode": 2,
+                    "mainid": null,
+                    "resetrate": null,
+                    "staterate": null,
+                    "failrate": null,
+                    "warningrecordsid": null
+                },
+                {
+                    "id": "9459be59-5baf-4557-8696-3adb76a2f2e4",
+                    "windpowerstationid": "GL_FDC",
+                    "windturbineid": "广灵第023台风机",
+                    "stoptime": "2022-08-03T01:23:04.000+0000",
+                    "starttime": null,
+                    "stophours": null,
+                    "losspower": null,
+                    "stoptypeid": "维护停机",
+                    "ishandle": null,
+                    "warningid": null,
+                    "projectid": "GL01_GC",
+                    "handleway": null,
+                    "faultview": null,
+                    "statuscode": 4,
+                    "mainid": null,
+                    "resetrate": null,
+                    "staterate": null,
+                    "failrate": null,
+                    "warningrecordsid": null
+                },
+            ],
+            stationList: [
+                {
+                    "id": "WNS_FDC",
+                    "code": "WNS_FDC",
+                    "name": "太旗卧牛山风电场",
+                    "address": "太旗卧牛山风电场",
+                    "telephone": null,
+                    "capacity": 148.5,
+                    "capacityunit": "MW",
+                    "quantity": 99,
+                    "aname": "卧牛山风电场",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP77-1500/UP77-1500-1/UP77-1500-2",
+                    "ordernum": 1,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "YY_FDC",
+                    "code": "YY_FDC",
+                    "name": "右玉高家堡风电场  ",
+                    "address": "右玉高家堡风电场  ",
+                    "telephone": null,
+                    "capacity": 198,
+                    "capacityunit": "MW",
+                    "quantity": 132,
+                    "aname": "高家堡风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP82-1500/UP82-1500-1/UP86-1500/UP86-1500-1/UP86-1500-2/UP86-1500-3/UP86-1500-4/MY-1.5se",
+                    "ordernum": 2,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "PL_FDC",
+                    "code": "PL_FDC",
+                    "name": "平鲁虎头山风电场  ",
+                    "address": "平鲁虎头山风电场  ",
+                    "telephone": null,
+                    "capacity": 223.5,
+                    "capacityunit": "MW",
+                    "quantity": 110,
+                    "aname": "虎头山风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "GW77-1500/GW82-1500/UP3000-120/GW109-2500",
+                    "ordernum": 3,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "GL_FDC",
+                    "code": "GL_FDC",
+                    "name": "广灵劲风风电场  ",
+                    "address": "广灵劲风风电场  ",
+                    "telephone": null,
+                    "capacity": 48,
+                    "capacityunit": "MW",
+                    "quantity": 24,
+                    "aname": "劲风风电场  ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP2000-105s",
+                    "ordernum": 4,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "HY_FDC",
+                    "code": "HY_FDC",
+                    "name": "浑源峰岳风电场 ",
+                    "address": "浑源峰岳风电场 ",
+                    "telephone": null,
+                    "capacity": 149.5,
+                    "capacityunit": "MW",
+                    "quantity": 80,
+                    "aname": "峰岳风电场 ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP82-1500-2/UP86-1500-2/UP2000-96/UP2000-105s",
+                    "ordernum": 5,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "FS_FDC",
+                    "code": "FS_FDC",
+                    "name": "方山宝塔山风电场 ",
+                    "address": "方山宝塔山风电场 ",
+                    "telephone": null,
+                    "capacity": 96,
+                    "capacityunit": "MW",
+                    "quantity": 48,
+                    "aname": "宝塔山风电场 ",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP2000-105s/UP2000-96",
+                    "ordernum": 6,
+                    "altitude": 1000,
+                    "height": null
+                },
+                {
+                    "id": "YG_FDC",
+                    "code": "YG_FDC",
+                    "name": "阳高采凉山风电场",
+                    "address": "阳高采凉山风电场",
+                    "telephone": null,
+                    "capacity": 90,
+                    "capacityunit": "MW",
+                    "quantity": 45,
+                    "aname": "采凉山风电场",
+                    "longitude": 1000,
+                    "latitude": 1000,
+                    "photo": null,
+                    "companyid": "1",
+                    "systemmanufact": null,
+                    "headfarm": null,
+                    "headfarmphone": null,
+                    "model": "UP2000-115s",
+                    "ordernum": 7,
+                    "altitude": 1000,
+                    "height": null
+                }
+            ],
+            typeList:[
+                {
+                    value: 2,
+                    name: '故障',
+                },
+                {
+                    value: 4,
+                    name: '维护',
+                },
+            ],
+            typeStatus: '',
+        };
+    },
+    created() {
+        let date = new Date();
+        this.timeValue[0] = date.getTime() - 86400000;
+        this.timeValue[1] = date.getTime() - 86400000;
+        this.getStation()
+    },
+    methods: {
+        getStation() {
+            api.getStation().then(res => {
+                if (res.data) {
+                    this.stationList = res.data.data
+                    this.getTableData()
+                }
+            })
+        },
+        getTableData() {
+            api.getShutdownevent({
+                wpid: this.selectValue,
+                beginDate: dayjs(this.timeValue[0]).format("YYYY-MM-DD"),
+                endDate: dayjs(this.timeValue[1]).format("YYYY-MM-DD"),
+                type: this.typeStatus,
+            }).then(res => {
+                if (res.data) {
+                    res.data.data.forEach(item => {
+                        if (item.stoptime) {
+                            item.stoptime = dayjs(item.stoptime).format("YYYY-MM-DD HH:mm:ss")
+                        }
+                        if (item.starttime) {
+                            item.starttime = dayjs(item.starttime).format("YYYY-MM-DD HH:mm:ss")
+                        }
+                    });
+                    this.tableList = res.data.data
+                }
+            })
+        },
+        exportExcel() {
+            // 数据源
+            let data = [];
+            this.tableList.forEach((item) => {
+                let values = {
+                    风机: item.windturbineid,
+                    停机时间: item.stoptime,
+                    恢复时间: item.starttime,
+                    停机小时: item.stophours,
+                    损失电量: item.losspower,
+                    停机类型: item.stoptypeid,
+                };
+                data.push(values);
+            });
+            // 下载的路径
+            let fileName = `风机停机分析.xlsx`;
+            let filePath = fileName;
+            // 新建workbook
+            const wb = XLSX.utils.book_new();
+            // 新建worksheet,并载入数据
+            const ws = XLSX.utils.json_to_sheet(data);
+            // 设置每列的列宽,10代表10个字符,注意中文占2个字符
+            ws["!cols"] = [{ wch: 20 }, { wch: 25 }, { wch: 25 }, { wch: 10 }, { wch: 10 }, { wch: 25 }];
+            // 生成xlsx文件(workbook,worksheet数据,sheet命名)
+            XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
+
+            // 写文件(workbook,xlsx文件路径+文件名)
+            XLSX.writeFile(wb, filePath);
+        },
+    },
+}
+</script>
+<style lang="less" scoped>
+.title-list {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-top: 10px;
+
+    .search {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .date {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .query-item {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .lable {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .button {
+        width: 80px;
+        height: 40px;
+        margin-left: 30px;
+    }
+}
+</style>

+ 256 - 0
src/views/tablePage3/index.vue

@@ -0,0 +1,256 @@
+<template>
+    <div>
+        <div class="title-list">
+            <div class="search">
+                <div class="date">风场:</div>
+                <el-cascader v-model="selectValue" :options="stationList" :props="defaultProps" :show-all-levels="false" @change="handleChange"></el-cascader>
+            </div>
+            <div class="search">
+                <div class="date">频率:</div>
+                <el-select class="inputs" v-model="interval" placeholder="请选择">
+                    <el-option v-for="item in lists" :key="item.value" :label="item.value" :value="item.value">
+                    </el-option>
+                </el-select>
+                <div class="date">分钟</div>
+            </div>
+            <div class="query-item">
+                <div class="lable">日期:</div>
+                <div class="search-input">
+                    <el-date-picker v-model="timeValue" type="datetimerange" range-separator="至" start-placeholder="开始日期"
+                        end-placeholder="结束日期">
+                    </el-date-picker>
+                </div>
+            </div>
+            <div class="query-actions">
+                <button class="button" @click="getTableData">查询</button>
+                <button class="button" @click="exportExcel">导出</button>
+            </div>
+        </div>
+        <div class="lables">
+            <el-checkbox-group v-model="checkList" @change="handleCheckedCitiesChange">
+                <el-checkbox v-for="(item, index) in typeList" :key="index" :label="item.name"></el-checkbox>
+            </el-checkbox-group>
+        </div>
+        <div>
+            <el-table height="90vh" ref="multipleTable" empty-text="暂无数据" :data="tableList" stripe
+                style="width: 100%; margin-bottom: 10px">
+                <el-table-column prop="wtname" label="风机" align="center"  width="220" sortable></el-table-column>
+                <el-table-column label="时间" prop="time" align="center" sortable>
+                </el-table-column>
+                <el-table-column v-for="(item, index) in checkList" :key="index" :label="item" :prop="typeList.find(val =>val.name == item).id" align="center" sortable>
+                </el-table-column>
+            </el-table>
+        </div>
+    </div>
+</template>
+<script>
+import api from "api/index";
+import dayjs from "dayjs";
+import XLSX from "xlsx";
+export default {
+    data() {
+        return {
+            timeValue: [],
+            checkList: ['风速(m/s)','功率(kw)'],
+            selectValue: [],
+            defaultProps: {
+                children: "data",
+                label: 'code',
+                value: 'id',
+            },
+            tableList: [
+                {
+                    "time":1661443200000,
+                    "wtid":"WNS01_011",
+                    "wtname":"1C11",
+                    "ai022":9.72,
+                    "ai130":565.6
+                },
+                {
+                    "time":1661445000000,
+                    "wtid":"WNS01_011",
+                    "wtname":"1C11",
+                    "ai022":7.96,
+                    "ai130":558.2
+                },
+                {
+                    "time":1661446800000,
+                    "wtid":"WNS01_011",
+                    "wtname":"1C11",
+                    "ai022":8.56,
+                    "ai130":604.3
+                },
+            ],
+            stationList: [
+                
+            ],
+            typeList:[
+                {
+                    "id":"ai022",
+                    "name":"风速(m/s)"
+                },
+                {
+                    "id":"ai130",
+                    "name":"功率(kw)"
+                },
+                {
+                    "id":"ai010",
+                    "name":"风向"
+                },
+                {
+                    "id":"ai036",
+                    "name":"对风角度"
+                }
+            ],
+            lists:[
+                {
+                    value: 10,
+                },
+                {
+                    value: 30,
+                },
+                {
+                    value: 60,
+                },
+            ],
+            interval: 30,
+            typeStatus: '',
+        };
+    },
+    created() {
+        let date = new Date();
+        this.timeValue[0] = new Date(new Date(new Date().toLocaleDateString()).getTime());
+        this.timeValue[1] = date.getTime();
+        this.getStation()
+    },
+    methods: {
+        handleChange(val){
+            console.log(val);
+        },
+        getStation() {
+            api.wtls().then(res => {
+                if (res.data) {
+                    this.stationList = res.data.data
+                    this.selectValue = [res.data.data[0].id,res.data.data[0].data[0].id]
+                    this.getPoints()
+                }
+            })
+        },
+        getPoints(){
+            api.points().then(res => {
+                if (res.data) {
+                    let arr = []
+                    this.typeList = res.data.data
+                    arr.push(res.data.data[0].name)
+                    arr.push(res.data.data[1].name)
+                    this.checkList = arr
+                    this.getTableData()
+                }
+            })
+        },
+        handleCheckedCitiesChange(){
+            this.getTableData()
+        },
+        getTableData() {
+            let arr = []
+            this.checkList.forEach(item =>{
+              arr.push(this.typeList.find(val =>val.name === item).id)
+            })
+            let uniformcodes = arr.join(',')
+            api.freedomList({
+                wtid: this.selectValue[1],
+                beginDate:  new Date(this.timeValue[0]).getTime(),
+                endDate: new Date(this.timeValue[1]).getTime(),
+                uniformcodes: uniformcodes,
+                interval: this.interval,
+            }).then(res => {
+                if (res.data) {
+                    res.data.data.forEach(item => {
+                        if (item.time) {
+                            item.time = dayjs(item.time).format("YYYY-MM-DD HH:mm:ss")
+                        }
+                    });
+                    this.tableList = res.data.data
+                }
+            })
+        },
+        exportExcel() {
+            // 数据源
+            let data = [];
+            this.tableList.forEach((item) => {
+                let values = {
+                    风机: item.wtname,
+                    时间: item.time,
+                }
+                this.checkList.forEach(val =>{
+                    values[val] = item[this.typeList.find(v => v.name === val).id]
+                })
+                    
+                data.push(values);
+            });
+            // 下载的路径
+            let fileName = `风机自由分析.xlsx`;
+            let filePath = fileName;
+            // 新建workbook
+            const wb = XLSX.utils.book_new();
+            // 新建worksheet,并载入数据
+            const ws = XLSX.utils.json_to_sheet(data);
+            // 设置每列的列宽,10代表10个字符,注意中文占2个字符
+            ws["!cols"] = [{ wch: 20 }, { wch: 25 },];
+            // 生成xlsx文件(workbook,worksheet数据,sheet命名)
+            XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
+
+            // 写文件(workbook,xlsx文件路径+文件名)
+            XLSX.writeFile(wb, filePath);
+        },
+    },
+}
+</script>
+<style lang="less" scoped>
+.title-list {
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    margin-top: 10px;
+
+    .search {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .date {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+
+        .inputs{
+            width: 75px;
+            margin-right: 10px;
+        }
+    }
+
+    .query-item {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        margin-left: 30px;
+
+        .lable {
+            margin-right: 20px;
+            font-size: 18px;
+        }
+    }
+
+    .button {
+        width: 80px;
+        height: 40px;
+        margin-left: 30px;
+    }
+}
+.lables{
+    width: 90%;
+    padding: 20px 5%;
+    line-height: 22px;
+}
+</style>

+ 45 - 0
vue.config.js

@@ -0,0 +1,45 @@
+const path = require('path');
+function resolve(dir) {
+    return path.join(__dirname, dir)
+}
+module.exports = {
+    publicPath: "./", // 默认'/',部署应用包时的基本 URL
+    indexPath: 'index.html', // 相对于打包路径index.html的路径
+    outputDir: 'dist', // 'dist', 生产环境构建文件的目录
+    assetsDir: 'static', // 相对于outputDir的静态资源(js、css、img、fonts)目录
+    lintOnSave: true, // 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
+    runtimeCompiler: true, // 是否使用包含运行时编译器的 Vue 构建版本
+    chainWebpack: (config) => {
+        config.resolve.alias
+            .set('@$', resolve('src'))
+            .set('assets', resolve('src/assets'))
+            .set('components', resolve('src/components'))
+            .set('layout', resolve('src/layout'))
+            .set('base', resolve('src/base'))
+            .set('static', resolve('src/static'))
+            .set("api", resolve("src/api"))
+            .set("utils", resolve("src/utils"))
+            .set("views", resolve("src/views"))
+            .set("styles", resolve("src/assets/styles"))
+            .set("img", resolve("src/assets/img"))
+            .set("icons", resolve("src/assets/icons"))
+            .set("router", resolve("src/router"))
+    },
+    configureWebpack: {
+        devtool: 'source-map'
+    },
+    pluginOptions: {
+        electronBuilder: {
+            nodeIntegration: true,
+            builderOptions: {
+                appId: 'com.neic.gyee',
+                win: {
+                    icon: 'src/assets/img/logo.ico'
+                },
+                linux: {
+
+                }
+            }
+        }
+    }
+}