Ver código fonte

初始化上传

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 1 mês atrás
pai
commit
f40a79cde1
100 arquivos alterados com 22112 adições e 7267 exclusões
  1. 2 3
      .env.development
  2. 0 3
      .env.eapi
  3. 1 6
      .env.production
  4. 1 1
      .gitignore
  5. 4 1
      README.md
  6. 4191 3112
      package-lock.json
  7. 15 9
      package.json
  8. 425 76
      src/App.vue
  9. 353 48
      src/api/index.js
  10. 1 0
      src/assets/dataService/README.md
  11. 234 0
      src/assets/dataService/arcgis-mhs-line.json
  12. 707 0
      src/assets/dataService/arcgis-mhs.json
  13. 1 0
      src/assets/dataService/arcgis-nss-line.json
  14. 1502 0
      src/assets/dataService/arcgis-nss.json
  15. 1 0
      src/assets/dataService/arcgis-qs-line.json
  16. 1007 0
      src/assets/dataService/arcgis-qs.json
  17. 173 0
      src/assets/dataService/arcgis-sbq-line.json
  18. 1757 0
      src/assets/dataService/arcgis-sbq.json
  19. 1 0
      src/assets/dataService/arcgis-xs-line.json
  20. 887 0
      src/assets/dataService/arcgis-xs.json
  21. BIN
      src/assets/img/PV/close.png
  22. BIN
      src/assets/img/PV/pv_arrow_pic.png
  23. BIN
      src/assets/img/PV/pv_box_pic.png
  24. BIN
      src/assets/img/PV/pv_box_transformer.png
  25. BIN
      src/assets/img/PV/pv_elec_pic.png
  26. BIN
      src/assets/img/PV/pv_nb_pic.png
  27. BIN
      src/assets/img/PV/pv_pic.png
  28. BIN
      src/assets/img/PV/pv_state_blue.png
  29. BIN
      src/assets/img/PV/pv_state_gre.png
  30. BIN
      src/assets/img/PV/pv_state_grey.png
  31. BIN
      src/assets/img/PV/pv_state_org.png
  32. BIN
      src/assets/img/PV/pv_state_red.png
  33. BIN
      src/assets/img/PV/pv_state_un.png
  34. BIN
      src/assets/img/PV/pv_state_vio.png
  35. BIN
      src/assets/img/PV/zhengti.png
  36. BIN
      src/assets/img/controlcenter/warning.png
  37. BIN
      src/assets/img/menu/agc.png
  38. BIN
      src/assets/img/menu/booster.png
  39. BIN
      src/assets/img/menu/homePage.png
  40. BIN
      src/assets/img/menu/lock.png
  41. BIN
      src/assets/img/menu/matrix.png
  42. BIN
      src/assets/img/menu/screenshot.png
  43. BIN
      src/assets/img/menu/search.png
  44. BIN
      src/assets/img/menu/set.png
  45. BIN
      src/assets/img/menu/unlock.png
  46. BIN
      src/assets/img/menu/unvoice.png
  47. BIN
      src/assets/img/menu/voice.png
  48. BIN
      src/assets/img/menu/webMisc.png
  49. BIN
      src/assets/img/type/duration.png
  50. 10 0
      src/assets/styles/main.css
  51. 81 155
      src/components/BasicInformationDetail.vue
  52. 1 0
      src/components/BoosterStation/dwk.vue
  53. 1 0
      src/components/BoosterStation/hzj.vue
  54. 1 0
      src/components/BoosterStation/mch.vue
  55. 1 1
      src/components/BoosterStation/mhs.vue
  56. 1 0
      src/components/BoosterStation/nss.vue
  57. 1 0
      src/components/BoosterStation/pl1.vue
  58. 1 0
      src/components/BoosterStation/pl2.vue
  59. 1 0
      src/components/BoosterStation/qs.vue
  60. 1 0
      src/components/BoosterStation/sbdl.vue
  61. 1 0
      src/components/BoosterStation/sbq.vue
  62. 1 0
      src/components/BoosterStation/xh.vue
  63. 1 0
      src/components/BoosterStation/xs.vue
  64. 454 0
      src/components/PvDetailPages.vue
  65. 485 235
      src/components/WindturbineDetailPages.vue
  66. 1165 0
      src/components/allMatrices.vue
  67. 454 396
      src/components/basicDataDetails.vue
  68. 200 170
      src/components/boxSelect.vue
  69. 171 157
      src/components/check/areaCard.vue
  70. 379 362
      src/components/check/operationRecords.vue
  71. 206 184
      src/components/control/areaCard.vue
  72. 445 259
      src/components/control/controlAllArea.vue
  73. 34 36
      src/components/control/controlArea.vue
  74. 318 0
      src/components/control/parametersContrast.vue
  75. 5 6
      src/components/dataDetails.vue
  76. 849 0
      src/components/eaxyMatrixBlock.vue
  77. 2 7
      src/components/focus/PhotoelectricDetailPages.vue
  78. 41 90
      src/components/focus/agcDetails.vue
  79. 34 32
      src/components/focus/currentWarningCard.vue
  80. 143 15
      src/components/focus/dataDetails.vue
  81. 151 139
      src/components/focus/detailsCharts.vue
  82. 115 21
      src/components/focus/focusArea.vue
  83. 232 263
      src/components/focus/focusCard.vue
  84. 89 84
      src/components/focus/multiple-line-chart.vue
  85. 691 231
      src/components/focus/syzDetails.vue
  86. 274 104
      src/components/matrixBlock.vue
  87. 926 0
      src/components/matrixBlockPv.vue
  88. 380 385
      src/components/modeControl/detailPages.vue
  89. 731 549
      src/components/modeControl/modeControl.vue
  90. 93 0
      src/components/panel/panel-no-title.vue
  91. 73 0
      src/components/panel/panel-sand-toolbar.vue
  92. 78 0
      src/components/panel/panel-sand.vue
  93. 112 0
      src/components/panel/panel.vue
  94. 139 0
      src/components/panel/panel2.vue
  95. 52 0
      src/components/panel/panel3.vue
  96. 46 0
      src/components/panel/toolbar-panel.vue
  97. 2 1
      src/components/problem/ProblemArea.vue
  98. 309 126
      src/components/problem/areaCard.vue
  99. 868 0
      src/components/search/action.vue
  100. 0 0
      src/components/search/calendar.vue

+ 2 - 3
.env.development

@@ -1,8 +1,7 @@
 VUE_APP_API=http://192.168.10.18:8099
-VUE_APP_WARNING=http://192.168.10.18:8070
 VUE_APP_SHARDINGURL=http://192.168.10.18:8075
 VUE_APP_ADAPTERURL=http://192.168.10.18:8011
 VUE_APP_APIS=192.168.10.18:8099
-VUE_APP_SHARDINGURLS=192.168.10.18:8075
 VUE_APP_ADAPTERURLS=192.168.10.18:8011
-VUE_APP_WARNINGS=92.168.10.18:8070
+VUE_APP_APT=http://192.168.10.4:8099
+

+ 0 - 3
.env.eapi

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

+ 1 - 6
.env.production

@@ -1,10 +1,5 @@
-# VUE_APP_API=http://18.6.30.53:8075
-# VUE_APP_IMAGE=http://18.6.30.53:8075
 VUE_APP_API=http://18.6.30.63:8099
-VUE_APP_WARNING=http://18.6.30.63:8070
-VUE_APP_SHARDINGURL=http://18.6.30.53:8075
+VUE_APP_SHARDINGURL=http://18.6.30.63:8075
 VUE_APP_ADAPTERURL=http://18.6.30.63:8011
 VUE_APP_APIS=18.6.30.63:8099
-VUE_APP_SHARDINGURLS=18.6.30.53:8075
 VUE_APP_ADAPTERURLS=18.6.30.63:8011
-VUE_APP_WARNINGS=18.6.30.63:8070

+ 1 - 1
.gitignore

@@ -28,4 +28,4 @@ pnpm-debug.log*
 #压缩包
 *.zip
 *.rar
-*.7z
+*.7z

+ 4 - 1
README.md

@@ -1,4 +1,4 @@
-# newneic
+# project-neic
 
 ## Project setup
 ```
@@ -17,3 +17,6 @@ npm run build
 
 ### Customize configuration
 See [Configuration Reference](https://cli.vuejs.org/config/).
+
+
+采用node 14 版本

Diferenças do arquivo suprimidas por serem muito extensas
+ 4191 - 3112
package-lock.json


+ 15 - 9
package.json

@@ -1,12 +1,12 @@
 {
-  "name": "newneic",
-  "version": "0.1.0",
+  "name": "project-neic",
+  "version": "2.2.1",
   "private": true,
   "scripts": {
     "serve": "vue-cli-service serve",
     "build": "vue-cli-service build",
-    "eb": "vue-cli-service electron:build",
-    "es": "vue-cli-service electron:serve",
+    "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"
   },
@@ -16,14 +16,20 @@
     "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",
+    "element-plus": "^1.1.0-beta.4",
+    "file-saver": "^2.0.5",
+    "html2canvas": "^1.4.1",
+    "jquery": "^3.6.0",
+    "json-bigint": "^1.0.0",
     "register-service-worker": "^1.7.1",
     "stompjs": "^2.3.3",
-    "vue": "^3.0.0",
+    "vue": "^3.0.11",
+    "vue-grid-layout": "^3.0.0-beta1",
     "vue-router": "^4.0.0-0",
     "vuex": "^4.0.0-0",
-    "xlsx": "^0.17.1"
+    "xlsx": "^0.17.5",
+    "xlsx-js-style": "^1.2.0",
+    "xlsx-style": "^0.8.13"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "~4.5.0",
@@ -36,7 +42,7 @@
     "electron-devtools-installer": "^3.1.0",
     "less": "^3.0.4",
     "less-loader": "^5.0.0",
-    "node-sass": "^4.12.0",
+    "node-sass": "^4.14.1",
     "sass-loader": "^8.0.2",
     "vue-cli-plugin-electron-builder": "~2.1.1"
   },

+ 425 - 76
src/App.vue

@@ -1,105 +1,350 @@
 <template class="app">
-  <div :class="$store.state.showWarningMask ? 'warningMask' : ''"></div>
-  <TitleBar class="titleBar" />
-  <div class="right">
-    <el-col>
-      <el-row>
-        <el-col>
-          <ModeControl
-            ref="modeControl"
-            :current="current"
-            @clicks="handleClick"
-          ></ModeControl>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col>
-          <FocusArea />
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col>
-          <WarningArea></WarningArea>
-        </el-col>
-      </el-row>
-    </el-col>
+  <div style="background-color: #000000" ref="imageTofile">
+    <div v-if="lockMaskDisplay" class="lockMask"></div>
+    <!-- <div class="warningMask"></div> -->
+    <TitleBar class="titleBar" />
+    <div class="left" v-if="!webMisc">
+      <Menu :lockMaskDisplay="lockMaskDisplay" :voiceCV="voiceCV" :temperatureNum="temperatureNum" @handleChange="handleChange"
+        @handleSearch="handleSearch" />
+    </div>
+    <div class="right">
+      <el-col>
+        <el-row>
+          <el-col>
+            <ModeControl ref="modeControl" :current="current" @clicks="handleClick"></ModeControl>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col>
+            <FocusArea />
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col>
+            <WarningArea></WarningArea>
+          </el-col>
+        </el-row>
+      </el-col>
+    </div>
+    <div class="Dialog" v-show="state">
+      <div class="D-" @click="none">-</div>
+    </div>
+    <StatusBar class="statusBar" @getData="getData" />
+    <router-view />
+    <AllMatrices v-model="matricesDisplay" />
+    <SYZDetails v-model="syzDialogShow" :activeTabStation="activeTabStation"></SYZDetails>
+    <AGCDetails v-model="agcDisplay"></AGCDetails>
+    <WebMisc v-model="webMisc"></WebMisc>
+    <TemperatureMatrix v-model="temperatureDisplay" />
+    <Fault v-model="faultDisplay" />
+    <Warning v-model="warningDisplay" />
+    <Status v-model="statusDisplay" />
+    <Action v-model="actionDisplay" />
+    <Calendar v-model="calendarDisplay" />
+    <Record v-model="recordDisplay" />
+    <State v-model="stateDisplay" />
+    <Setting v-model="settingDisplay" />
+    
   </div>
-  <StatusBar class="statusBar" />
-  <router-view />
 </template>
 <script>
 import TitleBar from "views/TitleBar.vue";
 import StatusBar from "views/StatusBar.vue";
+import Menu from "views/Menu.vue";
 import MessageBridge from "utils/MessageBridge";
 import ModeControl from "components/modeControl/modeControl.vue";
 import FocusArea from "components/focus/focusArea.vue";
 import WarningArea from "components/warning/warningArea.vue";
-
 import api from "api/index";
-
+import boxSelect from "components/boxSelect.vue";
+import AGCDetails from "components/focus/agcDetails.vue";
+import SYZDetails from "components/focus/syzDetails.vue";
+import WebMisc from "components/webMisc.vue";
+import AllMatrices from "components/allMatrices.vue";
+import Setting from "components/setting.vue";
+import TemperatureMatrix from "components/temperatureMatrix.vue";
+import Fault from "components/search/fault.vue";
+import Warning from "components/search/warning.vue";
+import Status from "components/search/status.vue";
+import Action from "components/search/action.vue";
+import html2canvas from "html2canvas";
+import Calendar from "components/search/calendar.vue";
+import Record from "components/search/record.vue";
+import State from "components/search/state.vue";
+import { debounce } from "lodash";
 export default {
+  data() {
+    return {
+      state: false,
+      agcDisplay: false, //AGC功能
+      matricesDisplay: false, //全部矩阵
+      temperatureDisplay: false, //温度矩阵
+      faultDisplay: false, //查询-报警/故障查询
+      warningDisplay: false, //查询-预警查询
+      statusDisplay: false, //查询-状态时间查询
+      actionDisplay: false, //查询-动作查询
+      lockMaskDisplay: false, //锁屏
+      voiceCV: false,
+      webMisc: false,//样本库
+      syzDialogShow: false,
+      settingDisplay: false,
+      recordDisplay: false, //查询-推荐记录
+      stateDisplay: false, //查询-状态变化查询
+      calendarDisplay: false, //查询-日历查询
+      temperatureNum: 0, //温度矩阵故障数
+      activeTabStation: '',
+    };
+  },
   components: {
     TitleBar,
     StatusBar,
+    Menu,
     ModeControl,
     FocusArea,
     WarningArea,
+    boxSelect,
+    AGCDetails,
+    SYZDetails,
+    WebMisc,
+    AllMatrices,
+    TemperatureMatrix,
+    Fault,
+    Warning,
+    Status,
+    Action,
+    Setting,
+    Calendar,
+    Record,
+    State,
   },
-  created() {
+  created: function () {
+    this.getStation();
     this.initData();
-    this.subscribe();
   },
   methods: {
-    initData() {
+    getData(val) {
+      this.state = val;
+    },
+    none() {
+      this.state = false;
+    },
+
+    initData: function () {
       let mb = MessageBridge.getInstance();
-      let windturbine = [
-        { key: "/topic/windturbine", action: this.windturbineMessage },
+      let temperature = [
+        { key: "/topic/temperature-count", action: this.debounceTemperatureMessage },
+      ];
+      let vss = [
+        { key: "/topic/voice-control", action: this.windturbineMessage },
       ];
-      let popup = [{ key: "/topic/fault-popup", action: this.faultMessage }];
-      let title = [{ key: "/topic/title-info", action: this.titleInfos }];
-      // var heartbeat = [{ key: "/topic/heartbeat-data", action: this.heartbeat }];
-      // mb.register(heartbeat);
-      mb.register(title);
-      mb.register(windturbine);
-      mb.register(popup);
+      mb.register(vss);
+      mb.register(temperature);
     },
-    windturbineMessage(msg) {
+    debounceTemperatureMessage: debounce(function (msg) {
+      this.temperatureMessage(msg)
+    }, 1000),
+    temperatureMessage(msg) {
       let json = JSON.parse(msg);
-      this.$store.commit("windturbinelist", json);
+      this.temperatureNum = json.countOverLimit + json.countCrossingLimit;
     },
-    faultMessage(msg) {
-      let json = JSON.parse(msg);
-      this.$store.commit("warning", json);
+    windturbineMessage(msg) {
+      let arr = msg.split("-");
+      if (msg === "CLOSE") {
+        this.handleClosed()
+      }
+      if (msg === "OPEN_FJJZ-ALL") {
+        this.handleChange(2)
+      }
+      if (msg === "OPEN_WDJZ-ALL") {
+        this.handleChange(3)
+      }
+      if (msg === "OPEN_AGC-ALL") {
+        this.handleChange(5)
+      }
+      if (arr[0] === "OPEN_SYZ") {
+        this.activeTabStation = arr[1]
+        this.handleClosed()
+        setTimeout(() => {
+          this.handleChange(4,true)
+        }, 3000);
+      }
+    },
+    getStation() {
+      api.getStation().then((res) => {
+        // let stationList = [];
+        let stationList = res.data;
+        // res.data.forEach((item) => {
+        //   if (item.type === 1) {
+        //     stationList.push(item);
+        //   }
+        // });
+        this.$store.commit("stationList", stationList);
+        let syzArray = [];
+        stationList.forEach((item) => {
+          let obj = {
+            id: item.id, // 升压站 ID
+            isWarning: "0", // 升压站是否显示报警小红点
+            name: item.name, // 升压站中文名称
+            isMute: false, // 升压站报警是否静音
+          };
+          syzArray.push(obj);
+        });
+        this.$store.commit("syzArray", syzArray);
+        this.$store.commit("activeTab", syzArray[0].name);
+      });
     },
-    // heartbeat(msg){
-    //   console.log(msg);
-    // },
-    subscribe() {
-      setTimeout(() => {
-        this.subscribe();
-      }, 20000);
-      if (!this.$store.state.observers) {
-        let mb = MessageBridge.getInstance();
-        let windturbine = [
-          { key: "/topic/windturbine", action: this.windturbineMessage },
-        ];
-        let popup = [{ key: "/topic/fault-popup", action: this.faultMessage }];
-        let title = [{ key: "/topic/title-info", action: this.titleInfos }];
-        let suggestion = [
-          { key: "/topic/suggestion", action: this.suggestion },
-        ];
-        mb.register(suggestion);
-        mb.register(title);
-        mb.register(windturbine);
-        mb.register(popup);
-        this.$store.commit("observers", true);
+    handleChange(val,flag) {
+      if (val !== 10) {
+        this.matricesDisplay = false;
+        this.syzDialogShow = false;
+        // this.$store.commit("syzDialogShow", false);
+        this.agcDisplay = false;
+        this.temperatureDisplay = false;
+        this.faultDisplay = false;
+        this.warningDisplay = false;
+        this.statusDisplay = false;
+        this.actionDisplay = false;
+        this.settingDisplay = false
+        this.calendarDisplay = false;
+        this.recordDisplay = false;
+        this.stateDisplay = false;
+      }
+
+      switch (val) {
+        case 2:
+          this.matricesDisplay = true;
+          break;
+        case 3:
+          this.temperatureDisplay = true;
+          break;
+        case 4:
+          if (flag) {
+            this.syzDialogShow = true;
+          } else {
+            this.activeTabStation = ''
+            this.syzDialogShow = true;
+          }
+          
+          break;
+        case 5:
+          this.agcDisplay = true;
+          break;
+        case 7:
+          this.webMisc = true;
+          break;
+        case 8:
+          this.lockMaskDisplay = !this.lockMaskDisplay;
+          break;
+        case 9:
+          this.voiceCV = !this.voiceCV;
+          break;
+        case 10:
+          this.toImage();
+          break;
+        case 11:
+          this.settingDisplay = true;
+          break;
+        default:
+          break;
       }
     },
+    handleClosed() {
+      this.matricesDisplay = false;
+      this.syzDialogShow = false;
+      // this.$store.commit("syzDialogShow", false);
+      this.agcDisplay = false;
+      this.temperatureDisplay = false;
+      this.faultDisplay = false;
+      this.warningDisplay = false;
+      this.statusDisplay = false;
+      this.actionDisplay = false;
+      this.settingDisplay = false
+      this.calendarDisplay = false;
+      this.recordDisplay = false;
+      this.stateDisplay = false;
+    },
+    handleSearch(val) {
+      this.matricesDisplay = false;
+      this.$store.commit("syzDialogShow", false);
+      this.agcDisplay = false;
+      this.temperatureDisplay = false;
+      this.faultDisplay = false;
+      this.warningDisplay = false;
+      this.statusDisplay = false;
+      this.actionDisplay = false;
+      this.settingDisplay = false;
+      this.calendarDisplay = false;
+      this.recordDisplay = false;
+      this.stateDisplay = false;
+      switch (val) {
+        case "fault":
+          this.faultDisplay = true;
+          break;
+        case "warning":
+          this.warningDisplay = true;
+          break;
+        case "status":
+          this.statusDisplay = true;
+          break;
+        case "action":
+          this.actionDisplay = true;
+          break;
+        case "calendar":
+          this.calendarDisplay = true;
+          break;
+        case "record":
+          this.recordDisplay = true;
+          break;
+        case "changeState":
+          this.stateDisplay = true;
+          break;
+        default:
+          break;
+      }
+    },
+    // 页面元素转图片
+    toImage() {
+      // 手动创建一个 canvas 标签
+      const canvas = document.createElement("canvas");
+      // 获取父标签,意思是这个标签内的 DOM 元素生成图片
+      // imageTofile是给截图范围内的父级元素自定义的ref名称
+      let canvasBox = this.$refs.imageTofile;
+      // 获取父级的宽高
+      const width = parseInt(window.getComputedStyle(canvasBox).width);
+      const height = parseInt(window.getComputedStyle(canvasBox).height);
+      // 宽高 * 2 并放大 2 倍 是为了防止图片模糊
+      canvas.width = width * 2;
+      canvas.height = height * 2;
+      canvas.style.width = width + "px";
+      canvas.style.height = height + "px";
+      const context = canvas.getContext("2d");
+      context.scale(2, 2);
+      const options = {
+        backgroundColor: null,
+        canvas: canvas,
+        useCORS: true,
+      };
+      html2canvas(canvasBox, options).then((canvas) => {
+        // toDataURL 图片格式转成 base64
+        let dataURL = canvas.toDataURL("image/png");
+        console.log(dataURL);
+        this.downloadImage(dataURL);
+      });
+    },
+    //下载图片
+    downloadImage(url) {
+      // 如果是在网页中可以直接创建一个 a 标签直接下载
+      let a = document.createElement("a");
+      a.href = url;
+      a.download = "页面截图";
+      a.click();
+    },
   },
 };
 </script>
 <style>
 @import "../src/assets/styles/main.css";
+
 body {
   /* 设置内容不可选中 */
   -webkit-user-select: none;
@@ -111,8 +356,46 @@ body {
 /* .app{
     background-color: #000000;
   } */
+.Dialog {
+  width: 520px;
+  height: 800px;
+  background-color: rgb(250, 249, 249);
+  position: absolute;
+  right: 30px;
+  z-index: 999;
+  bottom: 50px;
+  /* display: none; */
+}
+
+.D- {
+  width: 30px;
+  height: 30px;
+  background-color: rgb(167, 204, 192);
+  font-size: 30px;
+  position: absolute;
+  top: 5px;
+  right: 10px;
+  line-height: 30px;
+  text-align: center;
+}
+
+.D-:hover {
+  background-color: #999999;
+}
+
+.left {
+  width: 40px;
+  position: absolute;
+  left: 0px;
+  height: 100%;
+  z-index: 9999;
+  background-color: #242424;
+  margin-left: 7px;
+  border-radius: 8px;
+}
+
 .right {
-  width: 32%;
+  width: 31%;
   position: absolute;
   right: 20px;
   z-index: 99;
@@ -123,6 +406,7 @@ body {
   position: absolute;
   bottom: 0;
   left: 0;
+  z-index: 9999;
 }
 
 .titleBar {
@@ -130,41 +414,87 @@ body {
   position: relative;
   top: 0;
   left: 0;
+  z-index: 999;
+}
+
+.el-table__body-wrapper::-webkit-scrollbar-thumb {
+  background-color: #999999;
+  border-radius: 8px;
+}
+
+.el-collapse-item__wrap {
+  background-color: #000000 !important;
+  box-sizing: border-box !important;
+  padding-left: 27px !important;
+}
+
+.el-collapse-item__header {
+  background-color: rgb(20, 20, 20) !important;
+  font-size: 12px !important;
+  color: #bfbfbf !important;
+  box-sizing: border-box !important;
+  padding-left: 30px !important;
+  margin-bottom: 2px !important;
 }
+
+.el-collapse {
+  border: none !important;
+}
+
+.el-collapse-item__header {
+  border: none !important;
+}
+
+.el-collapse-item__wrap {
+  border: none !important;
+}
+
+.lockMask {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  background-color: rgba(0, 0, 0, 0.2);
+  z-index: 9998;
+}
+
 .warningMask {
   width: 100%;
   height: 100%;
   position: absolute;
-  background-image: radial-gradient(
-    circle,
-    rgb(255, 0, 0, 0),
-    rgb(255, 0, 0, 0),
-    rgb(255, 0, 0, 0),
-    rgb(255, 0, 0)
-  );
+  background-image: radial-gradient(circle,
+      rgb(255, 0, 0, 0),
+      rgb(255, 0, 0, 0),
+      rgb(255, 0, 0, 0),
+      rgb(255, 0, 0));
   animation: fade 2000ms infinite;
   -webkit-animation: fade 2000ms infinite;
   z-index: 999;
   pointer-events: none;
 }
+
 @keyframes fade {
   from {
     opacity: 0.7;
   }
+
   50% {
     opacity: 0.3;
   }
+
   to {
     opacity: 0.7;
   }
 }
+
 @-webkit-keyframes fade {
   from {
     opacity: 0.7;
   }
+
   50% {
     opacity: 0.3;
   }
+
   to {
     opacity: 0.7;
   }
@@ -179,8 +509,27 @@ body {
   }
 
   .currentScroll::-webkit-scrollbar-thumb {
-    background-color: #292929;
+    background-color: #999999;
     border-radius: 6px;
   }
 }
+
+::-webkit-scrollbar {
+  width: 8px !important;
+  height: 8px !important;
+  background-color: black !important;
+}
+
+::-webkit-scrollbar-thumb {
+  background-color: #999999 !important;
+  border-radius: 6px !important;
+}
+
+.el-table--enable-row-hover .el-table__body tr:hover>td {
+  color: rgba(37, 116, 219, 0.8) !important;
+}
+
+.el-table__body tr.current-row>td {
+  color: rgba(37, 116, 219, 0.8) !important;
+}
 </style>

+ 353 - 48
src/api/index.js

@@ -1,25 +1,122 @@
 import request from "../utils/request";
+//全部风机
+const getWindturbine = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/windturbine/all`,
+        method: "get",
+    });
+};
+// 获取所有升压站tab数据
+const getAllStationTab = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/boost_station/stations`,
+        method: "get",
+    });
+}
+// 获取svg触发器
+const getAllStationSvgInfo = (params) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/boost_station/svginfo?id=${params.id}`,
+        method: "get",
+    });
+}
+// 获取升压站svg图片数据
+const getSvgData = (params) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/boost_station/svg?id=${params.id}`,
+        method: "get",
+    });
+}
+// 获取矩阵页面光伏二级页左侧栏数据
+const getStationInfoData = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/station/pv_info`,
+        method: "get",
+    });
+}
+// 获取矩阵页面光伏二级页整体数据
+const getAllPvStationData = (params) => {
+    return request({
+        baseURL: process.env.VUE_APP_ADAPTERURL,
+        url: `/ts/latest?thingType=windturbine&thingId=${params.id}&uniformCodes=${params.codes}`,
+        method: "get",
+    });
+}
+// 获取矩阵页面光伏二级页echarts数据
+const getAllPvHistoryData = (params) => {
+    return request({
+        baseURL: process.env.VUE_APP_ADAPTERURL,
+        url: `/ts/history/snap?thingType=windturbine&thingId=${params.id}&uniformCode=${params.code}&startTs=${params.startTime}&endTs=${params.endTime}&interval=${params.interval}`,
+        method: "get",
+    });
+}
+
+// 标题栏数据
+const stationOverview = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/station/overview`,
+        method: "get",
+    });
+};
+//获取报警数据
+const alarmFault = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/alarm/fault`,
+        method: "get",
+    });
+};
+//获取推荐风机信息
+const recommendation = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/windturbine/recommendation`,
+        method: "get",
+    });
+};
 //登陆
 const login = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/user/login`,
         method: "post",
-        data:data,
+        data: data,
+    });
+};
+//获取场站
+const getStation = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/station/info`,
+        method: "get",
+    });
+};
+//获取AGC场站
+const getAGCStation = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/station/agc`,
+        method: "get",
     });
 };
 //刷新报警信息
 const getSnap = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_SHARDINGURL,
-        url: `/alarm/snap/page?pagenum=${data.pagenum}&pagesize=${data.pagesize}&category1=${data.category1}&isopened=${data.isopened}&starttime=${data.starttime}&endtime=${data.endtime}`,
+        baseURL: process.env.VUE_APP_SHARDINGURL,
+        url: `/alarm/snap/page?pagenum=${data.pagenum}&pagesize=${data.pagesize}&category1=${data.category1}&isopened=${data.isopened}&starttime=${data.starttime}&endtime=${data.endtime}&windturbineId=${data.windturbineId ? data.windturbineId : ''}`,
         method: "get",
     });
 };
 //数据刷新
 const refreshData = (keys) => {
     return request({
-        baseURL:process.env.VUE_APP_ADAPTERURL,
+        baseURL: process.env.VUE_APP_ADAPTERURL,
         url: `/ts/latest?keys=${keys}`,
         method: "get",
     });
@@ -27,124 +124,124 @@ const refreshData = (keys) => {
 //风机控制
 const windturbControl = (pairs) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/api/control/`,
         method: "post",
-        data:pairs
+        data: pairs
     });
 };
 //风机控制
 const windturbControlLock = (pairs) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/api/control/lock`,
         method: "post",
-        data:pairs
+        data: pairs
     });
 };
 //获取风机详情页面数据
 const nitWinturbineBaseData = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_ADAPTERURL,
+        baseURL: process.env.VUE_APP_ADAPTERURL,
         url: `/ts/latest?thingType=${data.thingType}&thingId=${data.thingId}&uniformCodes=${data.uniformCodes}`,
         method: "get",
     });
 };
 const getOverview = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/api/windturbine/overview`,
         method: "get",
     });
 };
 const sendWarning = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/alarm/confirm?snapID=${data.snapID}&faultID=${data.faultID}&userName=${data.userName}`,
         method: "get",
     });
 };
 const sendRecommend = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `api/voice-control/addvoicetask`,
         method: "post",
-        data:data
+        data: data
     });
 };
 const getPower = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_ADAPTERURL,
+        baseURL: process.env.VUE_APP_ADAPTERURL,
         url: `/ts/history/snap?tagName=${data.tagName}&startTs=${data.startTs}&endTs=${data.endTs}&interval=${data.interval}`,
         method: "get",
     });
 };
 const getOriginalPower = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_ADAPTERURL,
+        baseURL: process.env.VUE_APP_ADAPTERURL,
         url: `/ts/history/raw?tagName=${data.tagName}&startTs=${data.startTs}&endTs=${data.endTs}`,
         method: "get",
     });
 };
 const getWindturbinePower = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_ADAPTERURL,
+        baseURL: process.env.VUE_APP_ADAPTERURL,
         url: `/ts/history/snap?thingId=${data.thingId}&uniformCode=${data.uniformCode}&startTs=${data.startTs}&endTs=${data.endTs}&thingType=${data.thingType}&interval=${data.interval}`,
         method: "get",
     });
 };
 const getOriginalWindturbinePower = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_ADAPTERURL,
+        baseURL: process.env.VUE_APP_ADAPTERURL,
         url: `/ts/history/raw?thingId=${data.thingId}&uniformCode=${data.uniformCode}&startTs=${data.startTs}&endTs=${data.endTs}&thingType=${data.thingType}`,
         method: "get",
     });
 };
-const getWindWarning = (data,pageIndex,pageSize) => {
+const getWindWarning = (data, pageIndex, pageSize) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/alarm/real-time-alarm?objectId=${data}&pageIndex=${pageIndex}&pageSize=${pageSize}`,
         method: "get"
     });
 };
-const getHealthDate=(stid,wtid)=>{
+const getHealthDate = (stid, wtid) => {
     return request({
-        baseURL:process.env.VUE_APP_WARNING,
-        url:`/alarm/statistic?stId=${stid}&wtId=${wtid}`,
-        method:"get"
+        baseURL: process.env.VUE_APP_WARNING,
+        url: `/alarm/statistic?stId=${stid}&wtId=${wtid}`,
+        method: "get"
     })
 }
-const getDetial=(data)=>{
+const getDetial = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
-        url:`/api/windturbine/${data}`,
-        method:"get"
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/windturbine/${data}`,
+        method: "get"
     })
 }
-const getWarning=(data,wtid,pt)=>{
+const getWarning = (data, wtid, pt) => {
     return request({
-        baseURL:process.env.VUE_APP_WARNING,
-        url:`/alarm/list?stId=${data}&wtId=${wtid}&widget=${pt}`,
-        method:"get"
+        baseURL: process.env.VUE_APP_WARNING,
+        url: `/alarm/list?stId=${data}&wtId=${wtid}&widget=${pt}`,
+        method: "get"
     })
 }
-const getCustomerLock=()=>{
+const getCustomerLock = () => {
     return request({
         baseURL: process.env.VUE_APP_API,
-        url:`/api/windturbine/customer-lock`,
-        method:"get"
+        url: `/api/windturbine/customer-lock`,
+        method: "get"
     })
 }
 const controlRecord = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/control-record/search?stationId=${data.stationId}&userName=${data.userName}&windturbineId=${data.windturbineId}&startTime=${data.startTime}&endTime=${data.endTime}&pageSize=${data.pageSize}&pageIndex=${data.pageIndex}`,
         method: "get",
     });
 };
 const getLatest = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_ADAPTERURL,
+        baseURL: process.env.VUE_APP_ADAPTERURL,
         url: `/ts/latest?keys=${data}`,
         method: "get",
     });
@@ -152,28 +249,211 @@ const getLatest = (data) => {
 //获取智能模式下场站
 const getControlType = () => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/api/station/status`,
         method: "get",
     });
 };
 const uodateControlType = (data) => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/api/station/status/update?stationid=${data.stationid}&type=${data.type}&userName=${data.userName}`,
         method: "get",
     });
 };
-
+//获取UniformCodes数据
+const getUniformCodes = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/windturbine/uniform-code`,
+        method: "get",
+    });
+};
+const getBoostStation = () => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/station/boost-station`,
+        method: "get",
+    });
+};
+//获取风机code名称
 const getWindturbineFdc = () => {
     return request({
-        baseURL:process.env.VUE_APP_API,
+        baseURL: process.env.VUE_APP_API,
         url: `/api/windturbine/fdc`,
         method: "get",
     });
 };
+const getWindturbineWarning = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_SHARDINGURL,
+        url: `/alarm/history/page?pagenum=${data.pagenum}&pagesize=${data.pagesize}&windturbineid=${data.windturbineid ? data.windturbineid : ''}&starttime=${data.starttime}&endtime=${data.endtime}&keyword=${data.keyword ? data.keyword : ''}&stationid=${data.stationid ? data.stationid : ''}&category1=${data.category1 ? data.category1 : ''}`,
+        method: "get",
+    });
+};
+//获取报警历史数据
+const getFaultHistory = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_SHARDINGURL,
+        url: `/fault/history/listpage?pagenum=${data.pageIndex}&pagesize=${data.pageSize}&stationid=${data.stationid}&keyword=${data.keyword}&starttime=${data.startTime}&endtime=${data.endTime}`,
+        method: "get",
+    });
+};
+
+const stationCompared = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/station/compared?models=${data}`,
+        method: "get",
+    });
+};
+//温度矩阵
+const temperatureInfo = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/windturbine/temperature-info?id=${data.id}&status=${data.status}&pagenum=${data.pagenum}&pagesize=${data.pagesize}`,
+        method: "get",
+    });
+};
+//获取风机故障
+const alarmSnap = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/alarm/alarm-snap?windturbineId=${data.windturbineId}`,
+        method: "get",
+    });
+};
+
+//预警分析
+const analysisDetail = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_WARNING,
+        url: `/analysis/detail?station=${data.station}&startTs=${data.startTs}&endTs=${data.endTs}&interval=${data.interval}&wtId=${data.wtId}&name=${data.name}`,
+        method: "get",
+    });
+};
+//预警分析
+const alarmCountQuery = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_WARNING,
+        url: `/alarm/count/query/new2?stationid=${data.stationid}&startdate=${data.startdate}&enddate=${data.enddate}`,
+        method: "get",
+    });
+};
+//获取风场机型
+const getStationModels = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/station/models?stationid=${data.stationid}`,
+        method: "get",
+    });
+};
+//获取设置查询
+const getSettings = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/settings/recommendation?stationId=${data.stationId}&modelId=${data.modelId}`,
+        method: "get",
+    });
+};
+//修改设置
+const updateSettings = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/settings/recommendation`,
+        method: "post",
+        data: data
+    });
+};
+//状态时间查询
+const statusTime = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/windturbine/status-time?stationId=${data.stationid}&startTs=${data.startTs}&endTs=${data.endTs}`,
+        method: "get",
+    });
+};
+
+//推荐记录查询
+const recommended = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `control-record/recommended?pagesize=${data.pagesize}&pagenum=${data.pagenum}&stationid=${data.stationid}&windturbineid=${data.windturbineid}`,
+        method: "get",
+    });
+};
+
+//状态变化查询
+const statusChange = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/windturbine/status?startTs=${data.startTs}&endTs=${data.endTs}&pagesize=${data.pagesize}&pagenum=${data.pagenum}&windturbineId=${data.windturbineid}`,
+        method: "get",
+    });
+};
+
+//恢复默认设置
+const returnSetting = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/settings/recommendation/recover?stationId=${data.stationId}&modelId=${data.modelId}`,
+        method: "get",
+    });
+};
+
+//获取报警列表
+const warningSetting = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/settings/alarminfos?stationId=${data.stationId}&modelId=${data.modelId}`,
+        method: "get"
+    })
+}
+
+//获取预警列表
+const costumeSetting = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/api/settings/costume-alarminfos?stationId=${data.stationId}&modelId=${data.modelId}`,
+        method: "get"
+    })
+}
+
+//刷新报警信息
+const getAlarmSnap = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_SHARDINGURL,
+        url: `/alarm/snap?stationid=${data.stationid}&category1=${data.category1}&windturbineid=${data.windturbineid}&isopened=${data.isopened}`,
+        method: "get",
+    });
+};
+
+const getEvaluationData = (id) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/control-record/evaluation?id=${id || ""}`,
+        method: "get",
+    });
+};
+
+const getControlStatistics = (startTs, endTs,stationId) => {
+    return request({
+        baseURL: process.env.VUE_APP_API,
+        url: `/control-record/control-statistics?startTs=${startTs}&endTs=${endTs}&stationId=${stationId}`,
+        method: "get",
+    });
+}
+const getnb = (data) => {
+    return request({
+        baseURL: process.env.VUE_APP_APT,
+        url: `/api/windturbine/temperature-export?windturbineIds=${data.windturbineIds}&startTs=${data.startTs}&endTs=${data.endTs}`,
+        method: "get",
+    });
+}
 export default {
     login,
+    getStation,
+    getAGCStation,
     getSnap,
     refreshData,
     windturbControl,
@@ -195,12 +475,37 @@ export default {
     getLatest,
     getControlType,
     uodateControlType,
+    getUniformCodes,
+    getBoostStation,
     getWindturbineFdc,
-    getStation(){
-        return request({
-            baseURL:process.env.VUE_APP_API,
-            url: `/api/station/agc`,
-            method: "get",
-        });
-    }
+    getWindturbineWarning,
+    getFaultHistory,
+    stationCompared,
+    temperatureInfo,
+    alarmSnap,
+    analysisDetail,
+    alarmCountQuery,
+    statusTime,
+    getWindturbine,
+    getSvgData,
+    getStationInfoData,
+    getAllPvStationData,
+    getAllPvHistoryData,
+    getAllStationTab,
+    getAllStationSvgInfo,
+    stationOverview,
+    alarmFault,
+    recommendation,
+    getStationModels,
+    getSettings,
+    updateSettings,
+    warningSetting,
+    costumeSetting,
+    recommended,
+    statusChange,
+    returnSetting,
+    getAlarmSnap,
+    getEvaluationData,
+    getControlStatistics,
+    getnb
 };

+ 1 - 0
src/assets/dataService/README.md

@@ -0,0 +1 @@
+# 用于存放json数据文件 如果数据过大则需要单独打包

+ 234 - 0
src/assets/dataService/arcgis-mhs-line.json

@@ -0,0 +1,234 @@
+[
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "paths": [
+                [
+                    107.0644069,
+                    37.30000218
+                ],
+                [
+                    107.0609736,
+                    37.29027221
+                ],
+                [
+                    107.0545363,
+                    37.29431798
+                ],
+                [
+                    107.0488715,
+                    37.29385708
+                ],
+                [
+                    107.04561,
+                    37.29752713
+                ],
+                [
+                    107.0409322,
+                    37.30025821
+                ],
+                [
+                    107.0374346,
+                    37.30382554
+                ],
+                [
+                    107.0325208,
+                    37.30630038
+                ],
+                [
+                    107.0349455,
+                    37.30909941
+                ],
+                [
+                    107.0286155,
+                    37.30956022
+                ],
+                [
+                    107.0238519,
+                    37.31106208
+                ]
+            ]
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "width": 3
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "paths": [
+                [
+                    107.0649004,
+                    37.30542993
+                ],
+                [
+                    107.0527768,
+                    37.30129941
+                ],
+                [
+                    107.048614,
+                    37.30432051
+                ],
+                [
+                    107.0456958,
+                    37.30819486
+                ],
+                [
+                    107.0414472,
+                    37.31130101
+                ],
+                [
+                    107.0348811,
+                    37.31508967
+                ],
+                [
+                    107.0305467,
+                    37.31749588
+                ],
+                [
+                    107.0199444,
+                    37.31830556
+                ],
+                [
+                    107.0611238,
+                    37.30860447
+                ],
+                [
+                    107.0571327,
+                    37.31169354
+                ],
+                [
+                    107.0521975,
+                    37.31369028
+                ]
+            ]
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "width": 3
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "paths": [
+                [
+                    107.0693851,
+                    37.30322815
+                ],
+                [
+                    107.0744705,
+                    37.30041183
+                ],
+                [
+                    107.0696425,
+                    37.29628104
+                ],
+                [
+                    107.0717883,
+                    37.29213295
+                ],
+                [
+                    107.0662093,
+                    37.28824071
+                ],
+                [
+                    107.0567894,
+                    37.31587468
+                ],
+                [
+                    107.0560169,
+                    37.31988494
+                ],
+                [
+                    107.0506954,
+                    37.32184734
+                ],
+                [
+                    107.0727539,
+                    37.31087435
+                ],
+                [
+                    107.0761871,
+                    37.3067612
+                ],
+                [
+                    107.0820665,
+                    37.30641985
+                ]
+            ]
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "width": 3
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "paths": [
+                [
+                    107.0360184,
+                    37.32406563
+                ],
+                [
+                    107.0318985,
+                    37.32969639
+                ],
+                [
+                    107.0269525,
+                    37.33528407
+                ],
+                [
+                    107.0515966,
+                    37.32539657
+                ],
+                [
+                    107.0396662,
+                    37.33669159
+                ],
+                [
+                    107.0315766,
+                    37.34420644
+                ],
+                [
+                    107.0183909,
+                    37.34223611
+                ],
+                [
+                    107.0164329,
+                    37.33144098
+                ],
+                [
+                    107.0044997,
+                    37.32873236
+                ],
+                [
+                    107.0019168,
+                    37.33337322
+                ]
+            ]
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "width": 3
+        },
+        "popupTemplate": null
+    }
+]

+ 707 - 0
src/assets/dataService/arcgis-mhs.json

@@ -0,0 +1,707 @@
+[
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0674069,
+            "y": 37.3040218
+        },
+        "symbol": null,
+        "attributes": {
+            "objectid": 1,
+            "fc_code": "fc01",
+            "code": "升压站",
+            "type": "升压站"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0644069,
+            "y": 37.30000218
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG01",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0609736,
+            "y": 37.29027221
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG02",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0545363,
+            "y": 37.29431798
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG03",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0488715,
+            "y": 37.29385708
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG04",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.04561,
+            "y": 37.29752713
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG05",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0409322,
+            "y": 37.30025821
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG06",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0374346,
+            "y": 37.30382554
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG07",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0325208,
+            "y": 37.30630038
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG08",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0349455,
+            "y": 37.30909941
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG09",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0286155,
+            "y": 37.30956022
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG10",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0238519,
+            "y": 37.31106208
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG11",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0649004,
+            "y": 37.30542993
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG12",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0527768,
+            "y": 37.30129941
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG13",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.048614,
+            "y": 37.30432051
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG14",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0456958,
+            "y": 37.30819486
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG15",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0414472,
+            "y": 37.31130101
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG16",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0348811,
+            "y": 37.31508967
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG17",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0305467,
+            "y": 37.31749588
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG18",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0199444,
+            "y": 37.31830556
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG19",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0611238,
+            "y": 37.30860447
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG20",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0571327,
+            "y": 37.31169354
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG21",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0521975,
+            "y": 37.31369028
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG22",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0693851,
+            "y": 37.30322815
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG23",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0744705,
+            "y": 37.30041183
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG24",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0696425,
+            "y": 37.29628104
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG25",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0717883,
+            "y": 37.29213295
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG26",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0662093,
+            "y": 37.28824071
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG27",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0567894,
+            "y": 37.31587468
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG28",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0560169,
+            "y": 37.31988494
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG29",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0506954,
+            "y": 37.32184734
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG30",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0727539,
+            "y": 37.31087435
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG31",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0761871,
+            "y": 37.3067612
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG32",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0820665,
+            "y": 37.30641985
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG33",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0360184,
+            "y": 37.32406563
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG34",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0318985,
+            "y": 37.32969639
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG35",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0269525,
+            "y": 37.33528407
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG36",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0515966,
+            "y": 37.32539657
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG37",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0396662,
+            "y": 37.33669159
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG38",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0315766,
+            "y": 37.34420644
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG39",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0183909,
+            "y": 37.34223611
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG40",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0164329,
+            "y": 37.33144098
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG41",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0044997,
+            "y": 37.32873236
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG42",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    },
+    {
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 107.0019168,
+            "y": 37.33337322
+        },
+        "symbol": null,
+        "attributes": {
+            "fc_code": "MHS",
+            "code": "MG43",
+            "type": "风场"
+        },
+        "popupTemplate": null
+    }
+]

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 0
src/assets/dataService/arcgis-nss-line.json


Diferenças do arquivo suprimidas por serem muito extensas
+ 1502 - 0
src/assets/dataService/arcgis-nss.json


Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 0
src/assets/dataService/arcgis-qs-line.json


Diferenças do arquivo suprimidas por serem muito extensas
+ 1007 - 0
src/assets/dataService/arcgis-qs.json


+ 173 - 0
src/assets/dataService/arcgis-sbq-line.json

@@ -0,0 +1,173 @@
+[{
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"paths": [
+			[106.4515667, 37.60171667],
+			[106.4368167, 37.6033],
+			[106.4341333, 37.60171667],
+			[106.4250833, 37.60041667],
+			[106.4375, 37.5879],
+			[106.4398167, 37.5854],
+			[106.4510667, 37.57506667],
+			[106.4539333, 37.57455],
+			[106.4591, 37.57405],
+			[106.4753, 37.57543333],
+			[106.48525, 37.57398333],
+			[106.4558833, 37.59241667],
+			[106.4520667, 37.59083333],
+			[106.4503333, 37.5869],
+			[106.4539, 37.58436667],
+			[106.4588333, 37.58393333],
+			[106.4689667, 37.58508333],
+			[106.4557667, 37.58851667],
+			[106.4691, 37.58788333],
+			[106.4727167, 37.5859],
+			[106.4853833, 37.58373333],
+			[106.501, 37.57553333],
+			[106.4698833, 37.6003],
+			[106.4722333, 37.59011667],
+			[106.4838333, 37.59091667],
+			[106.4861333, 37.58858333],
+			[106.4880333, 37.58626667],
+			[106.4897833, 37.58736667],
+			[106.5011667, 37.58518333],
+			[106.5076667, 37.58378333],
+			[106.5184167, 37.5862],
+			[106.5253667, 37.58713333],
+			[106.5342833, 37.58786667]
+		]
+	},
+	"symbol": null,
+	"attributes": {
+		"fc_code": "SBQ",
+		"width": 3
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"paths": [
+			[106.4565333, 37.63861667],
+			[106.4537167, 37.63945],
+			[106.4505667, 37.64101667],
+			[106.4369333, 37.64116667],
+			[106.43425, 37.65011667],
+			[106.43735, 37.654],
+			[106.4381333, 37.65733333],
+			[106.4344, 37.65973333],
+			[106.4393167, 37.66668333],
+			[106.4433167, 37.667],
+			[106.45585, 37.65986667],
+			[106.4680167, 37.63951667],
+			[106.4685, 37.65056667],
+			[106.4562167, 37.6501],
+			[106.43795, 37.65021667],
+			[106.4415833, 37.65116667],
+			[106.4413667, 37.65436667],
+			[106.4417667, 37.65761667],
+			[106.4568333, 37.65378333],
+			[106.47095, 37.65178333],
+			[106.4699833, 37.65555],
+			[106.4736333, 37.66703333],
+			[106.4756167, 37.63865],
+			[106.4847167, 37.64136667],
+			[106.4739833, 37.64246667],
+			[106.4729333, 37.65466667],
+			[106.4751667, 37.6567],
+			[106.48745, 37.65055],
+			[106.4874333, 37.65305],
+			[106.4893333, 37.65453333],
+			[106.48695, 37.65755],
+			[106.4923667, 37.64303333],
+			[106.4925333, 37.6522]
+		]
+	},
+	"symbol": null,
+	"attributes": {
+		"fc_code": "SBQ",
+		"width": 3
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"paths": [
+			[106.4372667, 37.60863333],
+			[106.4358333, 37.62263333],
+			[106.4697, 37.62076667],
+			[106.4594167, 37.6087],
+			[106.4585833, 37.60526667],
+			[106.4248667, 37.617],
+			[106.48565, 37.63513333],
+			[106.4233833, 37.63723333],
+			[106.4683667, 37.63515],
+			[106.4348333, 37.61908333],
+			[106.4395333, 37.62545],
+			[106.4423, 37.62185],
+			[106.4758667, 37.63501667],
+			[106.451, 37.60971667],
+			[106.4543167, 37.60706667],
+			[106.4505, 37.62356667],
+			[106.4544833, 37.61888333],
+			[106.4586833, 37.62058333],
+			[106.4376833, 37.63785],
+			[106.4405167, 37.61908333],
+			[106.4345, 37.63703333],
+			[106.4260833, 37.62615],
+			[106.4693667, 37.61766667],
+			[106.4713333, 37.63703333],
+			[106.4408833, 37.60918333]
+		]
+	},
+	"symbol": null,
+	"attributes": {
+		"fc_code": "SBQ",
+		"width": 3
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"paths": [
+			[106.53535, 37.60373333],
+			[106.5314833, 37.60988333],
+			[106.5277833, 37.61066667],
+			[106.5195, 37.6084],
+			[106.5133333, 37.60538333],
+			[106.5099333, 37.62868333],
+			[106.5286667, 37.62028333],
+			[106.5286833, 37.62013333],
+			[106.5013167, 37.62301667],
+			[106.459833, 37.61241667],
+			[106.5030833, 37.61541667],
+			[106.4942667, 37.61318333],
+			[106.4932667, 37.61023333],
+			[106.4872, 37.61611667],
+			[106.4764833, 37.61796667],
+			[106.4820833, 37.61956667],
+			[106.485, 37.62698333],
+			[106.4895333, 37.63096667],
+			[106.4963, 37.6317],
+			[106.5025167, 37.62693333],
+			[106.5047, 37.63411667],
+			[106.5142, 37.63583333],
+			[106.5098667, 37.64313333],
+			[106.50405, 37.64968333],
+			[106.4992333, 37.6394]
+		]
+	},
+	"symbol": null,
+	"attributes": {
+		"fc_code": "SBQ",
+		"width": 3
+	},
+	"popupTemplate": null
+}]

Diferenças do arquivo suprimidas por serem muito extensas
+ 1757 - 0
src/assets/dataService/arcgis-sbq.json


Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 0
src/assets/dataService/arcgis-xs-line.json


+ 887 - 0
src/assets/dataService/arcgis-xs.json

@@ -0,0 +1,887 @@
+[{
+        "geometry": {
+            "spatialReference": {
+                "wkid": 4326
+            },
+            "x": 105.2139616,
+            "y": 37.17630397
+        },
+        "symbol": null,
+        "attributes": {
+            "objectid": 1,
+            "fc_code": "fc01",
+            "code": "升压站",
+            "type": "升压站"
+        },
+        "popupTemplate": null
+    },{
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2139616,
+		"y": 37.17630397
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG01",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2186394,
+		"y": 37.17746656
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG02",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2209997,
+		"y": 37.18197998
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG03",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2246046,
+		"y": 37.18398015
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG04",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2170515,
+		"y": 37.16939645
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG05",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2227592,
+		"y": 37.17149955
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG06",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2188325,
+		"y": 37.17346581
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG07",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2284241,
+		"y": 37.17165343
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG08",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2288532,
+		"y": 37.17532943
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG09",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2307415,
+		"y": 37.17856075
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG10",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2354193,
+		"y": 37.18136453
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG11",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2213216,
+		"y": 37.16744719
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG12",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2199697,
+		"y": 37.1630697
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG13",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2188754,
+		"y": 37.15821314
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG14",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2351832,
+		"y": 37.16212919
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG15",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2419209,
+		"y": 37.16488228
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG16",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2455902,
+		"y": 37.16595955
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG17",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2475214,
+		"y": 37.16895189
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG18",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2521992,
+		"y": 37.16784046
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG19",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2424788,
+		"y": 37.16185559
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG20",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2399254,
+		"y": 37.15814473
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG21",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2384663,
+		"y": 37.15386932
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG22",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2489376,
+		"y": 37.16094927
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG23",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2476501,
+		"y": 37.15793952
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG24",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2444744,
+		"y": 37.15532299
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG25",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2115583,
+		"y": 37.17213218
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG26",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2099276,
+		"y": 37.17526105
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG27",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2087474,
+		"y": 37.18179192
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG28",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2079105,
+		"y": 37.18509134
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG29",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2108502,
+		"y": 37.18861284
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG30",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1989198,
+		"y": 37.1755517
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG31",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1991987,
+		"y": 37.18280057
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG32",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.198791,
+		"y": 37.18815129
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG33",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1958299,
+		"y": 37.1801849
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG34",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1887488,
+		"y": 37.18856156
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG35",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1947355,
+		"y": 37.17633817
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG36",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1866031,
+		"y": 37.17977459
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG37",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1873326,
+		"y": 37.1755688
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG38",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1796722,
+		"y": 37.17688527
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG39",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1824403,
+		"y": 37.18757008
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG40",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1773977,
+		"y": 37.18500586
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG41",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1714969,
+		"y": 37.18526229
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG42",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2116871,
+		"y": 37.16691711
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG43",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2104855,
+		"y": 37.1634288
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG44",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.207417,
+		"y": 37.16799435
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG45",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.201602,
+		"y": 37.16690001
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG46",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2053785,
+		"y": 37.15397194
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG47",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.2037477,
+		"y": 37.15821314
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG48",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1997781,
+		"y": 37.15963252
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG49",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1993275,
+		"y": 37.15679373
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG50",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.194757,
+		"y": 37.15879457
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG51",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1912808,
+		"y": 37.16060726
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG52",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1859164,
+		"y": 37.15607546
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG53",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1862597,
+		"y": 37.15226171
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG54",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1868176,
+		"y": 37.1622147
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG55",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1817322,
+		"y": 37.16525848
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG56",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1725054,
+		"y": 37.16621604
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG57",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}, {
+	"geometry": {
+		"spatialReference": {
+			"wkid": 4326
+		},
+		"x": 105.1694369,
+		"y": 37.1642838
+	},
+	"symbol": null,
+	"attributes": {
+		"code": "XG58",
+		"fc_code": "XS",
+		"type": "风场"
+	},
+	"popupTemplate": null
+}]

BIN
src/assets/img/PV/close.png


BIN
src/assets/img/PV/pv_arrow_pic.png


BIN
src/assets/img/PV/pv_box_pic.png


BIN
src/assets/img/PV/pv_box_transformer.png


BIN
src/assets/img/PV/pv_elec_pic.png


BIN
src/assets/img/PV/pv_nb_pic.png


BIN
src/assets/img/PV/pv_pic.png


BIN
src/assets/img/PV/pv_state_blue.png


BIN
src/assets/img/PV/pv_state_gre.png


BIN
src/assets/img/PV/pv_state_grey.png


BIN
src/assets/img/PV/pv_state_org.png


BIN
src/assets/img/PV/pv_state_red.png


BIN
src/assets/img/PV/pv_state_un.png


BIN
src/assets/img/PV/pv_state_vio.png


BIN
src/assets/img/PV/zhengti.png


BIN
src/assets/img/controlcenter/warning.png


BIN
src/assets/img/menu/agc.png


BIN
src/assets/img/menu/booster.png


BIN
src/assets/img/menu/homePage.png


BIN
src/assets/img/menu/lock.png


BIN
src/assets/img/menu/matrix.png


BIN
src/assets/img/menu/screenshot.png


BIN
src/assets/img/menu/search.png


BIN
src/assets/img/menu/set.png


BIN
src/assets/img/menu/unlock.png


BIN
src/assets/img/menu/unvoice.png


BIN
src/assets/img/menu/voice.png


BIN
src/assets/img/menu/webMisc.png


BIN
src/assets/img/type/duration.png


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

@@ -72,6 +72,9 @@ body,
   background-color: rgb(29,106,235) !important;
 }
 
+.el-loading-mask{
+    background-color: black !important;
+}
 
 .el-table--border:after,.el-table--group:after,.el-table:before {
   background-color: black;
@@ -113,4 +116,11 @@ body,
   }
   .el-notification .el-icon-warning {
     color: #E6A23C !important;
+  }
+  .el-table td.el-table__cell, .el-table th.el-table__cell.is-leaf{
+    border-bottom: 2px solid black !important;
+  }
+  .el-table__body-wrapper::-webkit-scrollbar {
+    width: 10px;
+    height: 10px;
   }

+ 81 - 155
src/components/BasicInformationDetail.vue

@@ -9,65 +9,6 @@
         ></StandAloneImg>
       </el-col>
       <el-col :span="12" class="rights">
-        <!-- <div class="marks" v-if="healthInfo.bj">
-          <div class="healthInfo">健康指数:</div>
-          <div class="healthTable" v-if="healthInfo.other">
-            <div class="healthTitle">
-              <div class="name">名称</div>
-              <div class="level">等级</div>
-              <div class="times">重要报警次数</div>
-              <div class="times">一般报警次数</div>
-            </div>
-            <div :class="showIndex===3?'healthContent_on':'healthContent'" @click="chooseInfo(3)">
-              <div class="contentName">变桨</div>
-              <el-rate class="starLevel" v-model="healthInfo.bj.star" disabled :max="max" void-color="#141414"
-                text-color="#E8A20D">
-              </el-rate>
-              <div class="contentTimes">{{healthInfo.bj.heightCount}}</div>
-              <div class="contentTimess">{{healthInfo.bj.lowCount}}</div>
-            </div>
-            <div :class="showIndex===2?'healthContent_on':'healthContent'" @click="chooseInfo(2)">
-              <div class="contentName">齿轮箱</div>
-              <el-rate class="starLevel" v-model="healthInfo.clx.star" disabled :max="max" void-color="#242424"
-                text-color="#E8A20D">
-              </el-rate>
-              <div class="contentTimes">{{healthInfo.clx.heightCount}}</div>
-              <div class="contentTimess">{{healthInfo.clx.lowCount}}</div>
-            </div>
-            <div :class="showIndex===1?'healthContent_on':'healthContent'" @click="chooseInfo(1)">
-              <div class="contentName">发电机</div>
-              <el-rate class="starLevel" v-model="healthInfo.fdj.star" disabled :max="max" void-color="#141414"
-                text-color="#E8A20D">
-              </el-rate>
-              <div class="contentTimes">{{healthInfo.fdj.heightCount}}</div>
-              <div class="contentTimess">{{healthInfo.fdj.lowCount}}</div>
-            </div>
-            <div :class="showIndex===5?'healthContent_on':'healthContent'" @click="chooseInfo(5)">
-              <div class="contentName">液压</div>
-              <el-rate class="starLevel" v-model="healthInfo.yy.star" disabled :max="max" void-color="#141414"
-                text-color="#E8A20D">
-              </el-rate>
-              <div class="contentTimes">{{healthInfo.yy.heightCount}}</div>
-              <div class="contentTimess">{{healthInfo.yy.lowCount}}</div>
-            </div>
-            <div :class="showIndex===4?'healthContent_on':'healthContent'" @click="chooseInfo(4)">
-              <div class="contentName">偏航</div>
-              <el-rate class="starLevel" v-model="healthInfo.ph.star" disabled :max="max" void-color="#141414"
-                text-color="#E8A20D">
-              </el-rate>
-              <div class="contentTimes">{{healthInfo.ph.heightCount}}</div>
-              <div class="contentTimess">{{healthInfo.ph.lowCount}}</div>
-            </div>
-            <div :class="showIndex===6?'healthContent_on':'healthContent'">
-              <div class="contentName">其他</div>
-              <el-rate class="starLevel" v-model="healthInfo.other.star" disabled :max="max" void-color="#141414"
-                text-color="#E8A20D">
-              </el-rate>
-              <div class="contentTimes">{{healthInfo.other.heightCount}}</div>
-              <div class="contentTimess">{{healthInfo.other.lowCount}}</div>
-            </div>
-          </div>
-        </div> -->
         <div class="titleList">
           <div
             class="titleItem"
@@ -180,7 +121,7 @@
           </div>
         </div>
         <div class="label">
-          <div
+          <!-- <div
             class="button"
             v-if="types === 2"
             @click="sendCommand({ controlType: '1' })"
@@ -214,7 +155,7 @@
             @click="sendCommand({ controlType: '8' })"
           >
             取消维护
-          </div>
+          </div> -->
           <div
             class="button"
             v-if="selectValue !== ''"
@@ -271,11 +212,11 @@
                 'text-align': 'center',
               }"
             >
-              <el-table-column prop="time" label="时间" width="220">
+              <el-table-column prop="lastUpdateTime" label="时间" width="220">
               </el-table-column>
               <el-table-column prop="alertText" label="故障信息" width="280">
               </el-table-column>
-              <el-table-column prop="rankName" label="故障级别">
+              <el-table-column prop="rank" label="故障级别">
               </el-table-column>
             </el-table>
           </el-scrollbar>
@@ -329,6 +270,7 @@ export default {
       restaurants: [],
       lockValues: [],
       windDetails: [],
+      showWarningList: [],
       state1: "",
       showIndex: 1,
       starValue: 3,
@@ -374,7 +316,7 @@ export default {
       selectValue: "7",
       healthInfo: {},
       dataValues: {},
-      warning: ["-"],
+      warning: [],
       showData: [],
       partsName: "",
       modelData: {},
@@ -398,6 +340,8 @@ export default {
         "需要登录",
       ],
       recordData: [],
+      intervals: null,
+      refreshTimer: "",
     };
   },
   methods: {
@@ -428,9 +372,6 @@ export default {
           this.selectValue =
             msg.data.lockType === 0 ? "" : String(msg.data.lockType);
         }
-        setTimeout(() => {
-          this.getDetial();
-        }, 1000);
       });
     },
     getLocks() {
@@ -475,6 +416,23 @@ export default {
         });
     },
     async getWarning() {
+      await api.getAlarmSnap({
+          stationid: this.windturbine.stationId,
+          category1: 'windturbine',
+          windturbineid: this.windturbine.windturbineId,
+          isopened: 1,
+        })
+        .then((msg) => {
+          if (msg.data) {
+            this.warning = msg.data;
+            // this.warningDeal() 
+          }
+        })
+        .catch((err) => {
+          console.log(err);
+        });
+    },
+    warningDeal(){
       let parts = "";
       switch (this.showIndex) {
         case 1:
@@ -493,46 +451,13 @@ export default {
           parts = "yy";
           break;
       }
-      await api
-        .getWarning(
-          this.windturbine.stationId,
-          this.windturbine.windturbineId,
-          parts
-        )
-        .then((msg) => {
-          if (msg.data.code === 200) {
-            msg.data.data &&
-              msg.data.data.forEach((item) => {
-                item.time = dayjs(item.time).format("MM-DD HH:mm:ss");
-              });
-            this.warning = msg.data.data;
-          }
-        })
-        .catch((err) => {
-          console.log(err);
-        });
+      this.warning.forEach(item =>{
+        if(item.category3 === parts){
+          this.showWarningList.push(item)
+        }
+      })
+
     },
-    // chooseInfo(value) {
-    //   this.showIndex = value
-    //   switch (this.showIndex) {
-    //     case 1:
-    //       this.showData = this.BasicInfo.BasicInfo.filter(item => item.index === "part6")[0]?.param
-    //       break;
-    //     case 2:
-    //       this.showData = this.BasicInfo.BasicInfo.filter(item => item.index === "part8")[0]?.param
-    //       break;
-    //     case 3:
-    //       this.showData = this.BasicInfo.BasicInfo.filter(item => item.index === "part7")[0]?.param
-    //       break;
-    //     case 4:
-    //       this.showData = this.BasicInfo.BasicInfo.filter(item => item.index === "part10")[0]?.param
-    //       break;
-    //     case 5:
-    //       this.showData = this.BasicInfo.BasicInfo.filter(item => item.index === "part9")[0]?.param
-    //       break;
-    //   }
-    //   this.getWarning()
-    // },
     listedChange() {
       switch (this.selectValue) {
         case "8":
@@ -558,25 +483,22 @@ export default {
           break;
       }
     },
-    // labelChange() {
-    //   let values = BackgroundData.getInstance().Marks;
-    //   if (!values.filter(item => item.title = this.windturbine.windturbineId)[0]) {
-    //     this.menuClicked({ type: "marking" })
-    //   }
-    //   BackgroundData.getInstance().updateMarks(this.windturbine, this.state1);
-    // },
 
     start(bi) {
       this.BasicInfo = bi;
       // this.bindData();
       this.refreshData();
       this.getLocks();
-      this.getDetial();
+      this.intervals = setInterval(this.getDetial, 1000);
       this.records();
+      this.getWarning()
       this.refreshTimer = setInterval(this.refreshData, 3000);
     },
     end() {
+      clearInterval(this.intervals);
       clearInterval(this.refreshTimer);
+      this.intervals = null;
+      this.refreshTimer = null;
     },
     /* 刷新数据 */
     refreshData() {
@@ -587,7 +509,7 @@ export default {
 
     /* 获得数据 */
     onMessage(msg) {
-      this.BasicInfo.BasicInfo.forEach((element) => {
+      this.BasicInfo.forEach((element) => {
         element.param.forEach((im) => {
           let val = msg[im.code];
           if (typeof val !== "undefined") {
@@ -608,77 +530,63 @@ export default {
       });
       switch (this.showIndex) {
         case 1:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === "part6"
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 6
           )[0]?.param;
           break;
         case 2:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === "part8"
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 8
           )[0]?.param;
           break;
         case 3:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === "part7"
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 7
           )[0]?.param;
           break;
         case 4:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === "part10"
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 10
           )[0]?.param;
           break;
         case 5:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === "part9"
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 9
           )[0]?.param;
           break;
       }
     },
-
-    // bindData() {
-    //   this.BasicInfo.BasicInfo.forEach((element) => {
-    //     if (element.tag == "基本信息") {
-    //       this.generalInfo = element.param;
-    //     } else if (element.tag == "温度信息") {
-    //       this.temperatureInfo = element.param;
-    //     } else if (element.tag == "电网信息") {
-    //       this.powerGridInfo = element.param;
-    //     } else if (element.tag == "桨叶信息") {
-    //       this.pitchInfo = element.param;
-    //     }
-    //   });
-    // },
     selectSvg(index) {
       this.showIndex = index;
-      // this.showData = this.BasicInfo.BasicInfo.filter(item => item.index === `part${this.showIndex+5}`)[0]?.param
       switch (this.showIndex) {
         case 1:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === `part6`
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 6
           )[0]?.param;
           break;
         case 2:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === "part8"
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 8
           )[0]?.param;
           break;
         case 3:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === "part7"
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 7
           )[0]?.param;
           break;
         case 4:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === "part10"
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 10
           )[0]?.param;
           break;
         case 5:
-          this.showData = this.BasicInfo.BasicInfo.filter(
-            (item) => item.index === "part9"
+          this.showData = this.BasicInfo.filter(
+            (item) => item.index === 9
           )[0]?.param;
           break;
       }
-      this.getWarning();
+      // this.getWarning();
+      // this.warningDeal()
     },
     sendCommand(msg, windturbine) {
       let bd = BackgroundData.getInstance();
@@ -785,9 +693,9 @@ export default {
       }
       let tp = iserror ? "warning" : "success";
       let dt = iserror ? 0 : 4500;
-      if (!iserror) {
-        mss = "控制成功";
-      }
+      // if (!iserror) {
+      //   mss = "控制成功";
+      // }
 
       this.$notify({
         title: "控制",
@@ -797,6 +705,7 @@ export default {
         offset: 60,
         duration: 3000,
       });
+      this.getLocks();
     },
 
     /* 控制失败 */
@@ -820,6 +729,12 @@ export default {
           : timeValues[1]
         : date.getTime();
       let startTs = timeValues ? timeValues[0] : endTs - 28800000;
+      const loading = this.$loading({
+        lock: true,
+        text: "数据加载中",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
       api
         .getWindturbinePower({
           thingId: windturbineId
@@ -836,8 +751,10 @@ export default {
             this.windDetails = res.data;
             this.partsName = value.name;
             this.display = true;
+            loading.close();
           } else {
             this.windDetails = [];
+            loading.close();
           }
         });
     },
@@ -851,6 +768,12 @@ export default {
           : timeValues[1]
         : date.getTime();
       let startTs = timeValues ? timeValues[0] : endTs - 28800000;
+      const loading = this.$loading({
+        lock: true,
+        text: "数据加载中",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
       api
         .getOriginalWindturbinePower({
           thingId: windturbineId
@@ -866,8 +789,10 @@ export default {
             this.windDetails = res.data;
             this.partsName = value.name;
             this.display = true;
+            loading.close();
           } else {
             this.windDetails = [];
+            loading.close();
           }
         });
     },
@@ -1109,7 +1034,7 @@ table {
 }
 
 .dataList {
-  width: 94%;
+  width: 97%;
   /* min-height: 250px; */
   height: 28vh;
   background-color: #141414;
@@ -1141,6 +1066,7 @@ table {
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
+  overflow: auto;
 }
 
 .dataBlock {

+ 1 - 0
src/components/BoosterStation/dwk.vue

@@ -5893,6 +5893,7 @@ export default {
   methods: {
     closed() {
       clearInterval(this.interval);
+      this.interval = null
     },
     refreshTPData() {
       this.boosterStation.getDatas("DWK_GDC", this.bindValue);

+ 1 - 0
src/components/BoosterStation/hzj.vue

@@ -4909,6 +4909,7 @@ export default {
   methods: {
     closed() {
       clearInterval(this.interval);
+      this.interval = null
     },
     refreshTPData() {
       this.boosterStation.getDatas("HZJ_GDC", this.bindValue);

+ 1 - 0
src/components/BoosterStation/mch.vue

@@ -2807,6 +2807,7 @@ import { BoosterStation } from "utils/BoosterStation";
 		methods: {
 			closed() {
 				clearInterval(this.interval);
+				this.interval = null
 			},
 			refreshTPData() {
 				this.boosterStation.getDatas("MCH_GDC", this.bindValue);

+ 1 - 1
src/components/BoosterStation/mhs.vue

@@ -9096,13 +9096,13 @@ export default {
   },
   created() {
     this.boosterStation = new BoosterStation();
-
     this.refreshTPData();
     this.interval = setInterval(this.refreshTPData, 1000);
   },
   methods: {
     closed() {
       clearInterval(this.interval);
+      this.interval = null
     },
     refreshTPData() {
       this.boosterStation.getDatas("MHS_FDC", this.bindValue);

+ 1 - 0
src/components/BoosterStation/nss.vue

@@ -5395,6 +5395,7 @@ import { BoosterStation } from "utils/BoosterStation";
 		methods: {
 			closed() {
 				clearInterval(this.interval);
+				this.interval = null
 			},
 			refreshTPData() {
 				this.boosterStation.getDatas("NSS_FDC",this.bindValue);

+ 1 - 0
src/components/BoosterStation/pl1.vue

@@ -5267,6 +5267,7 @@ export default {
   methods: {
     closed() {
       clearInterval(this.interval);
+      this.interval = null
     },
     refreshTPData() {
       this.boosterStation.getDatas("PL1_GDC", this.bindValue);

+ 1 - 0
src/components/BoosterStation/pl2.vue

@@ -3580,6 +3580,7 @@ import { BoosterStation } from "utils/BoosterStation";
 		methods: {
 			closed() {
 				clearInterval(this.interval);
+				this.interval = null
 			},
 			refreshTPData() {
 				this.boosterStation.getDatas("PL2_GDC",this.bindValue);

+ 1 - 0
src/components/BoosterStation/qs.vue

@@ -4013,6 +4013,7 @@ export default {
   methods: {
     closed() {
       clearInterval(this.interval);
+      this.interval = null
     },
     refreshTPData() {
       this.boosterStation.getDatas("QS_FDC", this.bindValue);

+ 1 - 0
src/components/BoosterStation/sbdl.vue

@@ -2465,6 +2465,7 @@ export default {
   methods: {
     closed() {
       clearInterval(this.interval);
+      this.interval = null
     },
     refreshTPData() {
       this.boosterStation.getDatas("QS3_FDC", this.bindValue);

+ 1 - 0
src/components/BoosterStation/sbq.vue

@@ -4366,6 +4366,7 @@ import { BoosterStation } from "utils/BoosterStation";
 		methods: {
 			closed() {
 				clearInterval(this.interval);
+				this.interval = null
 			},
 			refreshTPData() {
 				this.boosterStation.getDatas("SBQ_FDC",this.bindValue);

+ 1 - 0
src/components/BoosterStation/xh.vue

@@ -12144,6 +12144,7 @@ export default {
   methods: {
     closed() {
       clearInterval(this.interval);
+      this.interval = null
     },
     refreshTPData() {
       this.boosterStation.getDatas("XH_GDC", this.bindValue);

+ 1 - 0
src/components/BoosterStation/xs.vue

@@ -10391,6 +10391,7 @@ export default {
   methods: {
     closed() {
       clearInterval(this.interval);
+      this.interval = null
     },
     refreshTPData() {
       this.boosterStation.getDatas("XS_FDC", this.bindValue);

+ 454 - 0
src/components/PvDetailPages.vue

@@ -0,0 +1,454 @@
+<template>
+    <el-dialog width="80%" @opened="opened()" @closed="closed()" :show-close="false" custom-class="my-info-dialog">
+        <template #title>
+            <div style="margin-top: -10px; color: #ffffff">光伏详情</div>
+        </template>
+         <!-- v-loading="loading" -->
+        <div class="pvDetail">
+            <div class="pvLeftDetail">
+                <div class="commonSty titleFont">
+                    <span>逆变器编号:</span>
+                    <span style="width: 38%;color: #c3c3c3">{{windturbine.id}}</span>
+                </div>
+                <div class="commonSty titleFont">
+                    <span>逆变器状态</span>
+                    <div>
+                        <img :src="statusArr[windturbine.status]" alt="">
+                    </div>
+                </div>
+                <div v-for="(item, index) in nbqData" :key="index" class="commonSty arrSty">
+                    <div class="arrName">
+                        <span>{{item.name}}</span>
+                    </div>
+                    <div class="arrMsg">
+                        <div class="msgNum">
+                            <span style="padding-right: 20px">{{item.value}}</span>
+                        </div>
+                        <span style="width: 20%;color: #c3c3c3">{{item.unit}}</span>
+                    </div>
+                </div>
+            </div>
+            <div class="pvRightDetail">
+                <div class="pvRightDetail_top">
+                    <div class="pvRightTopTitle">
+                        <span>光伏板</span>
+                        <span v-if="showTitle(windturbine)">汇流箱</span>
+                        <span v-else>箱变</span>
+                        <span>逆变器</span>
+                        <span>电网</span>
+                    </div>
+                    <div class="pvRightBotImg">
+                        <div class="img1">
+                            <img src="../assets/img/PV/pv_pic.png" alt="">
+                        </div>
+                        <div class="imgCom">
+                            <img src="../assets/img/PV/pv_arrow_pic.png" alt="">
+                        </div>
+                        <div class="img2">
+                            <img src="../assets/img/PV/pv_box_pic.png" v-if="showTitle(windturbine)" alt="">
+                            <img src="../assets/img/PV/pv_box_transformer.png" v-else alt="">
+                        </div>
+                        <div class="imgCom">
+                            <img src="../assets/img/PV/pv_arrow_pic.png" alt="">
+                        </div>
+                        <div class="img3">
+                            <img src="../assets/img/PV/pv_nb_pic.png" alt="">
+                        </div>
+                        <div class="imgCom">
+                            <img src="../assets/img/PV/pv_arrow_pic.png" alt="">
+                        </div>
+                        <div>
+                            <img src="../assets/img/PV/pv_elec_pic.png" alt="">
+                        </div>
+                    </div>
+                </div>
+                <div class="pvRightDetail_bot">
+                    <div class="pvRightBotTitle">
+                        <span>功率曲线</span>
+                    </div>
+                    <div class="pvRightBotEchart" id="pvEchart"></div>
+                </div>
+            </div>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+import api from "api/index";
+import * as echarts from "echarts";
+
+import img0 from '../assets/img/PV/pv_state_gre.png'
+import img1 from '../assets/img/PV/pv_state_blue.png'
+import img2 from '../assets/img/PV/pv_state_red.png'
+import img3 from '../assets/img/PV/pv_state_grey.png'
+import img4 from '../assets/img/PV/pv_state_org.png'
+import img5 from '../assets/img/PV/pv_state_vio.png'
+import img6 from '../assets/img/PV/pv_state_un.png'
+export default {
+    props: {
+        windturbine: {
+            type: Object,
+            default: () => {
+                return {}
+            },
+        },
+    },
+    watch: {
+        windturbine: {
+            handler: function (json) {
+                if (json) {
+                    // this.initData();
+                }
+            },
+        },
+    },
+    data() {
+        return {
+            nbqData: [],
+            echartsData: [],
+            pvTitle: [],
+            startTimer: null,
+            echartTimer: null,
+            loading: false,
+            statusArr: []
+        };
+    },
+    computed: {
+        echartHeight() {
+            return {
+                'height': document.documentElement.clientHeight-30 + 'px'
+            }
+        }
+    },
+    created() {
+        this.statusArr = [img0, img1, img2, img3, img4, img5, img6]
+    },
+
+    methods: {
+        showTitle(data) {
+            let show = false
+            if (data.station.indexOf('HZJ') === -1) {
+                show = true
+            }
+            return show 
+        },
+        opened() {
+            this.getPvStationInfoData()
+            // this.loading = true
+        },
+        // 获取光伏详情配置
+        getPvStationInfoData() {
+            let that = this
+            that.echartsData = []
+            api.getStationInfoData().then(datas =>{
+                if (datas && datas.data) {
+                    console.log('windturbine', this.windturbine)
+                    for(let i in datas.data) {
+                        if (that.windturbine.station === i) {
+                            that.getPvStationData(datas.data[i].codeInfos)
+                            // that.startTimer = setInterval(() =>{
+                            //     that.getPvStationData(datas.data[i].codeInfos)
+                            // }, 3000)
+                            that.getEcharts(datas.data[i].codeInfos)
+                            // that.echartTimer = setInterval(() =>{
+                            //     that.getEcharts(datas.data[i].codeInfos)
+                            // }, 10000)
+                        }
+                    }
+                    
+                }
+            })
+        },
+        // 获取光伏详情配置数据
+        getPvStationData(list) {
+            console.log('list', list)
+            console.log('windturbine', this.windturbine)
+            let code = []
+            list.forEach(it =>{
+                code.push(it.code)
+            })
+            let params = {
+                id: this.windturbine.id,
+                codes: code.join(',')
+            }
+            api.getAllPvStationData(params).then(datas =>{
+                if (datas && datas.data) {
+                    list.forEach(it =>{
+                        if (it.code) {
+                            let codeFv = it.code.split(',')
+                            if (codeFv.length === 1) {
+                                for(let i in datas.data) {
+                                    if (it.code === i) {
+                                        it.value = datas.data[i].value.toFixed(2)
+                                    }
+                                }
+                            } else if (codeFv.length > 1) {
+                                for(let j =0; j<codeFv.length; j++) {
+                                    let codeVal = 0
+                                    for(let i in datas.data) {
+                                        if (codeFv[j] === i) {
+                                            codeVal += datas.data[i].value
+                                        }
+                                    }
+                                    it.value = codeVal.toFixed(2)
+                                }
+                            }
+                        } else {
+                            it.value = 0.00
+                        }
+                    })
+                    this.nbqData = list
+                }
+            })
+        },
+        // 获取曲线数据
+        getEcharts(data) {
+            let end = new Date().getTime()
+            for(let i =0; i<data.length; i++) {
+                let it = data[i]
+                if (it.type) {
+                    let params = {
+                        id: this.windturbine.id,
+                        code: it.code,
+                        startTime: end - 8*60*60*1000,
+                        endTime: end,
+                        interval: 60
+                    }
+                    api.getAllPvHistoryData(params).then(datas =>{
+                        let obj = {
+                            name: it.name,
+                            type: it.type,
+                            series: datas.data
+                        }
+                        this.echartsData.push(obj)
+                        if (this.echartsData.length === 3) {
+                            this.changeDataFormat(this.echartsData)
+                        }
+                    })
+                }
+            }
+        },
+        changeDataFormat(datas) {
+            let series = []
+            let xAxis = []
+            let legend = []
+            console.log('datas', datas)
+            datas.forEach((it, index) =>{
+                legend.push(it.name)
+                if (index === 0) {
+                    it.series.forEach(ic =>{
+                        let time = this.getTime(new Date(ic.ts))
+                        xAxis.push(time)
+                    })
+                }
+                let oneSeries = []
+                it.series.forEach(iv =>{
+                    oneSeries.push(iv.value)
+                })
+                let seriesObj = {
+                    name: it.name,
+                    type: 'line',
+                    data: oneSeries.map(ib => {
+                        return ib.toFixed(2)
+                    }),
+                    symbol: 'none'
+                }
+                series.push(seriesObj)
+            })
+            console.log('series', series)
+            console.log('xAxis', xAxis)
+            console.log('legend', legend)
+            this.getglobalLine('pvEchart', xAxis, legend, series)
+        },
+        getTime(date){ 
+            var h = date.getHours();  
+            h=h < 10 ? ('0' + h) : h;  
+            var minute = date.getMinutes();  
+            minute = minute < 10 ? ('0' + minute) : minute;  
+            var second=date.getSeconds();
+            second=second < 10 ? ('0' + second) : second;
+            return h + ':' + minute + ':' + second; 
+        },
+        closed(){
+            clearInterval(this.startTimer);
+            clearInterval(this.echartTimer);
+            this.startTimer = null
+            this.echartTimer = null
+        },
+        
+        getglobalLine(name, xAxis, legend, series) {
+            let option = {
+                backgroundColor: '#232d38',
+                tooltip: {
+                    trigger: 'axis'
+                },
+                legend: {
+                    data: legend
+                },
+                grid: {
+                    left: '5%',
+                    right: '4%',
+                    bottom: '3%',
+                    containLabel: true
+                },
+                xAxis: {
+                    type: 'category',
+                    boundaryGap: false,
+                    data: xAxis
+                },
+                yAxis: {
+                    type: 'value'
+                },
+                series: series
+            };
+            // 基于准备好的dom,初始化echarts实例
+            let dom = document.getElementById(name);
+            dom.removeAttribute("_echarts_instance_")
+            let myChart = echarts.init(dom, 'dark');
+            myChart.setOption(option);
+            this.loading = false
+            window.addEventListener("resize", function () {
+                myChart.resize()
+            })
+        },
+    }
+};
+</script>
+<style lang="less" scoped>
+.pvDetail {
+    background-color: black;
+    margin-top: -30px;
+    margin-left: -10px;
+    margin-right: -10px;
+    margin-bottom: -30px;
+    border-bottom: 20px solid rgb(36, 36, 36);
+    display: flex;
+    padding: 5px 10px;
+    .pvLeftDetail{
+        width: 20%;
+        .commonSty{
+            height: 40px;
+            background:#232d38;
+            border-radius: 10px;
+            margin-top: 10px;
+            span{
+                color: #fff;
+                display: inline-block;
+                position: relative;
+                top: 8px;
+                left: 16px;
+            }
+            img{
+                width: 20px;
+                height: 20px;
+                position: relative;
+                top: 10px;
+            }
+        }
+        .titleFont{
+            width: calc(100% - 20px);
+            font-size: 16px;
+            display: flex;
+            padding-right: 20px;
+            justify-content: space-between;
+        }
+        .arrSty{
+            display: flex;
+            justify-content: space-between;
+            span{
+                font-size: 14px;
+            }
+            .arrName{
+                width: 40%;
+                span{
+                    color: #c3c3c3;
+                }
+            }
+            .arrMsg{
+                width: 60%;
+                display: flex;
+                // justify-content: end;
+                padding-right: 20px;
+                .msgNum{
+                    width: 140px;
+                    span{
+                        padding-right: 20px;
+                        float: right;
+                    }
+                }
+                span{
+                    display: inline-block;
+                }
+            }
+        }
+    }
+    .pvRightDetail{
+        width: calc(80% - 10px);
+        padding-left: 10px;
+        .pvRightDetail_top{
+            background:#232d38;
+            border-radius: 10px;
+            margin-top: 10px;
+            .pvRightTopTitle{
+                display: flex;
+                justify-content: space-around;
+                height: 30px;
+                color: #253443;
+                border-bottom: 1px solid #5c5b5b;
+                padding: 5px 0;
+                margin-bottom: 10px;
+                span{
+                    color: #fff;
+                    margin-top: 3px;
+                }
+            }
+            .pvRightBotImg{
+                display: flex;
+                justify-content: space-around;
+                padding: 50px 0;
+                .img1{
+                    margin-top: 40px;
+                }
+                .img2{
+                    margin-top: 35px;
+                }
+                .img3{
+                    margin-top: 20px;
+                }
+                .imgCom{
+                    margin-top: 50px;
+                }
+            }
+        }
+        .pvRightDetail_bot{
+            background:#232d38;
+            border-radius: 10px;
+            margin-top: 10px;
+            height: 60%;
+            .pvRightBotTitle{
+                text-align: center;
+                height: 20px;
+                color: #253443;
+                border-bottom: 1px solid #5c5b5b;
+                padding: 10px 0;
+                margin-bottom: 10px;
+                span{
+                    color: #fff;
+                }
+            }
+            .pvRightBotEchart{
+                width: 100%;
+                // height: calc(100% - 70px);
+                height: 380px;
+            }
+        }
+    }
+}
+
+
+</style>
+<style lang="less">
+.my-info-dialog{
+    margin-top: 10vh !important;
+}
+</style>

+ 485 - 235
src/components/WindturbineDetailPages.vue

@@ -1,252 +1,502 @@
 <template>
-	<el-dialog width="75%" @opened="opened()" @closed="closed()" :show-close="false" class="my-info-dialog">
-		<template #title>
-			<div style="margin-top:-10px;color: #FFFFFF;">风机详情</div>
-		</template>
-		<div class="body">
-			<div class="titleList">
-				<div class="chunkdiv">
-					<div class="title">风机号:&emsp;</div>
-					<div>{{ windturbine.windturbineId }}</div>
-				</div>
-				<div class="chunkdiv" @dblclick="dbClicks(baseDate.windSpeed)">
-					<div class="title">{{baseDate.windSpeed.name}}:&emsp;</div>
-					<div>{{baseDate.windSpeed.value}}{{baseDate.windSpeed.unit}}</div>
-				</div>
-				<div class="chunkdiv" @dblclick="dbClicks({code: 'YDPJFS5M',name: '五分钟平均风速'})">
-					<div class="title">五分钟平均风速:&emsp;</div>
-					<div>{{healthInfo?.averageWindSpeed5?.toFixed(2)}}m/s</div>
-				</div>
-				<div class="chunkdiv" @dblclick="dbClicks(theoreticalPower)">
-					<div class="title">理论功率:&emsp;</div>
-					<div>{{healthInfo?.theoreticalPower?.toFixed(2)}}Kw</div>
-				</div>
-				<div class="chunkdiv" @dblclick="dbClicks(baseDate.power)">
-					<div class="title">{{baseDate.power.name}}:&emsp;</div>
-					<div>{{baseDate.power.value}}{{baseDate.power.unit}}</div>
-				</div>
-				<div class="chunkdiv" @dblclick="dbClicks(baseDate.generatorSpeed)">
-					<div class="title">{{baseDate.generatorSpeed.name}}:&emsp;</div>
-					<div>{{baseDate.generatorSpeed.value}}{{baseDate.generatorSpeed.unit}}</div>
-				</div>
-			</div>
-			<BasicInformationDetail ref="BasicInfo" :types="types" @health-click="handleHealth" :windturbine="windturbine"></BasicInformationDetail>
-		</div>
-	</el-dialog>
+  <el-dialog
+    width="80%"
+    @opened="opened()"
+    @closed="closed()"
+    :show-close="false"
+    class="my-info-dialog"
+  >
+    <template #title>
+      <div style="margin-top: -10px; color: #ffffff">风机详情</div>
+    </template>
+    <div class="body">
+      <div class="titleList">
+        <div class="chunkdiv" @click="handleClick(true)">
+          <div class="title">风机号:&emsp;</div>
+          <div>{{ windturbine.windturbineId }}</div>
+          <!-- <div>
+            {{ windturbine.stationId.slice(0, 2) }}-{{ windturbine.code }}
+          </div> -->
+        </div>
+        <div
+          class="chunkdiv"
+          @click="handleClick(true)"
+          @dblclick="dbClicks(baseDate.windSpeed)"
+        >
+          <div class="title">{{ baseDate.windSpeed.name }}:&emsp;</div>
+          <div>{{ baseDate.windSpeed.value }}{{ baseDate.windSpeed.unit }}</div>
+        </div>
+        <div
+          class="chunkdiv"
+          @click="handleClick(true)"
+          @dblclick="dbClicks({ code: 'YDPJFS5M', name: '五分钟平均风速' })"
+        >
+          <div class="title">五分钟平均风速:&emsp;</div>
+          <div>{{ healthInfo?.averageWindSpeed5?.toFixed(2) }}m/s</div>
+        </div>
+        <div
+          class="chunkdiv"
+          @click="handleClick(true)"
+          @dblclick="dbClicks(theoreticalPower)"
+        >
+          <div class="title">理论功率:&emsp;</div>
+          <div>{{ healthInfo?.theoreticalPower?.toFixed(2) }}Kw</div>
+        </div>
+        <div
+          class="chunkdiv"
+          @click="handleClick(true)"
+          @dblclick="dbClicks(baseDate.power)"
+        >
+          <div class="title">{{ baseDate.power.name }}:&emsp;</div>
+          <div>{{ baseDate.power.value }}{{ baseDate.power.unit }}</div>
+        </div>
+        <div
+          class="chunkdiv"
+          @click="handleClick(true)"
+          @dblclick="dbClicks(baseDate.generatorSpeed)"
+        >
+          <div class="title">{{ baseDate.generatorSpeed.name }}:&emsp;</div>
+          <div>
+            {{ baseDate.generatorSpeed.value
+            }}{{ baseDate.generatorSpeed.unit }}
+          </div>
+        </div>
+        <div class="chunkdiv" @click="handleClick(false)">
+          <div class="title">故障信息: &emsp;{{ faultNum }}</div>
+        </div>
+      </div>
+      <BasicInformationDetail
+        v-show="current"
+        ref="BasicInfo"
+        :types="types"
+        @health-click="handleHealth"
+        :windturbine="windturbine"
+      ></BasicInformationDetail>
+      <div class="faultInfo" v-show="!current">
+        <div class="left-item">
+          <div
+            :class="item.openedCount > 0 ? 'faultNameErr' : 'faultName'"
+            v-for="(item, index) in fault"
+            :key="index"
+            @click="handleFaultClick(index)"
+          >
+            {{ item.component }}
+            <div class="faultNum" v-if="item.openedCount > 0">
+              ({{ item.openedCount }})
+            </div>
+          </div>
+        </div>
+        <div class="right-item">
+          <div class="tables">
+            <el-table
+              :data="faultList"
+              class="table"
+              style="width: 100%"
+              height="67vh"
+              stripe
+              highlight-current-row
+              :header-cell-style="{
+                background: 'rgb(30,30,30)',
+                color: 'rgb(220,220,220)',
+                padding: '4px',
+                fontSize: '14px',
+                'border-bottom': 'solid 1px rgba(77, 77, 77, 1)',
+              }"
+              :cell-style="tableCellStyle"
+            >
+              <el-table-column
+                prop="id"
+                label="报警编号"
+                width="200"
+                align="center"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="modelId"
+                label="风机型号"
+                width="150"
+                align="center"
+              >
+              </el-table-column>
+              <el-table-column prop="alertText" label="报警信息" align="center">
+              </el-table-column>
+              <el-table-column label="故障状态" width="120" align="center">
+                <template #default="scope">
+                  <span>
+                    {{ scope.row.isOpened > 0 ? "故障" : "正常" }}
+                  </span>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </div>
+      </div>
+    </div>
+  </el-dialog>
 </template>
 
 <script>
-	// import YawDetail from "./YawDetail.vue";
-	import api from "api/index";
-	import BasicInformationDetail from "./BasicInformationDetail.vue";
-	import UniformCodes from "utils/UniformCodes";
-	import BackgroundData from 'utils/BackgroundData'
-	// import Worning from "./warning.vue"
-	export default {
-		components: {
-			BasicInformationDetail,
-		},
-		props: {
-			windturbine: Object,
-		},
-		data() {
-			return {
-				BasicInfo: {},
-				healthInfo: {},
-				line: "",
-				alarmTime: "",
-				alarmContent: "",
-				alarms: [],
-				count: false,
-				theoreticalPower:{
-					code: "LLGL",
-					name: "理论功率"
-				},
-				typeList: [{
-					type: 0,
-					name: '已经停机',
-				},
-				{
-					type: 1,
-					name: '上电',
-				},
-				{
-					type: 2,
-					name: '待机',
-				},
-				{
-					type: 3,
-					name: '启动',
-				},
-				{
-					type: 4,
-					name: '并网',
-				},
-				{
-					type: 5,
-					name: '故障',
-				},
-				{
-					type: 6,
-					name: '维护',
-				},
-				{
-					type: 7,
-					name: '离线',
-				},
-				],
-				baseDate: {
-					windSpeed: {
-						name: '',
-						num: '',
-						unit: ''
-					},
-					power: {
-						name: '',
-						num: '',
-						unit: ''
-					},
-					generatorSpeed: {
-						name: '',
-						num: '',
-						unit: ''
-					},
-				},
-				types: null,
-			};
-		},
-		created() {
-			this.UniformCodes = new UniformCodes();
-		},
+import api from "api/index";
+import BasicInformationDetail from "./BasicInformationDetail.vue";
+import BackgroundData from "utils/BackgroundData";
+import Fault from "utils/fault";
+export default {
+  components: {
+    BasicInformationDetail,
+  },
+  props: {
+    windturbine: Object,
+  },
+  data() {
+    return {
+      current: true,
+      BasicInfo: {},
+      healthInfo: {},
+      line: "",
+      alarmTime: "",
+      alarmContent: "",
+      alarms: [],
+      count: false,
+      theoreticalPower: {
+        code: "LLGL",
+        name: "理论功率",
+      },
+      typeList: [
+        {
+          type: 0,
+          name: "已经停机",
+        },
+        {
+          type: 1,
+          name: "上电",
+        },
+        {
+          type: 2,
+          name: "待机",
+        },
+        {
+          type: 3,
+          name: "启动",
+        },
+        {
+          type: 4,
+          name: "并网",
+        },
+        {
+          type: 5,
+          name: "故障",
+        },
+        {
+          type: 6,
+          name: "维护",
+        },
+        {
+          type: 7,
+          name: "离线",
+        },
+      ],
+      baseDate: {
+        windSpeed: {
+          name: "",
+          num: "",
+          unit: "",
+        },
+        power: {
+          name: "",
+          num: "",
+          unit: "",
+        },
+        generatorSpeed: {
+          name: "",
+          num: "",
+          unit: "",
+        },
+      },
+      types: null,
+      fault: {},
+      refreshTimer: "",
+      refreshTimers: "",
+      faultNum: 0,
+      faultList: [],
+      // station: [],
+    };
+  },
+  created() {
+    this.getUniformCodes();
+    // this.getWindturbineFdc();
+  },
 
-		methods: {
-			opened() {
-				this.line = "";
-					this.alarmTime = "";
-					this.alarmContent = "";
-					this.BasicInfo = this.UniformCodes.getStationInfos(this.windturbine);
-					this.BasicInfo.windturbineId = this.windturbine.windturbineId;
-					// this.dateDeal(this.BasicInfo)
-					this.$refs.BasicInfo.start(this.BasicInfo);
-					this.initData();
-					this.refreshData();
-					this.refreshTimer = setInterval(this.refreshData, 100)
-			},
-			closed() {
-				// todo 切换页面的时候应该让上一个页面停止刷新数据(调用end方法)
-				// this.$refs.svgRef.closed();
-				// this.$refs.BasicInfo.end();
-				// this.$refs.BasicInfo.labelChange();
-				this.$emit('close');
-				//clearInterval(this.refreshTimer);
-			},
-			dateDeal(BasicInfo) {
-				let showInf = {}
-				showInf = BasicInfo.BasicInfo.filter(item => item.tag === "基本信息")[0]
-				this.baseDate.windSpeed = showInf.param.filter(item => item.name === "风速")[0]
-				this.baseDate.power = showInf.param.filter(item => item.name === "有功功率")[0]
-				this.baseDate.generatorSpeed = showInf.param.filter(item => item.name === "发电机转速")[0]
-				this.baseDate.type = showInf.param.filter(item => item.name === "状态")[0].value ? this.typeList.filter(
-					status => status.type === Number(showInf.param.filter(item => item.name === "状态")[0].value))[0]
-					.name : ''
-				console.log(this.baseDate.generatorSpeed.name);
-				this.types = Number(showInf.param.filter(item => item.name === "状态")[0].value)
-				console.log(this.types)
-			},
-			refreshData() {
-				let bg = BackgroundData.getInstance();
-				bg.initWinturbineBaseData(this.BasicInfo, this.onMessage);
-				this.dateDeal(this.BasicInfo)
-				clearInterval(this.refreshTimer);
-				this.refreshTimer = setInterval(this.refreshData, 5000)
-			},
-			initData() {
-				// axiios.get(`http://${config.calcUrl}/windturbine/line/${this.windturbine.windturbineId}`)
-				//   .then(msg => this.line = msg.data);
-				api.getWindWarning(this.windturbine.windturbineId, '1', '50').then(msg => {
-					let vs = msg.data;
-					if (vs.length <= 0) return;
-					this.alarmTime = BackgroundData.getInstance().formatDate(vs[0].lastUpdateTime);
-					this.alarmContent = vs[0].alertText;
-					this.alarms = msg.data;
-					this.$refs.BasicInfo.alarmd(this.alarms);
-					console.log(this.alarms)
-				})
-					.catch(err => {
-						console.log(err);
-					});
-			},
-			dbClicks(value) {
-				this.$refs.BasicInfo.dbClicks(value, this.windturbine.windturbineId)
-			},
-			handleHealth(value){
-				this.healthInfo = value
-			}
-		},
-		watch: {
-			'windturbine': {
-				handler: function (json) {
-					if (json) {
-						this.initData()
-					}
-				}
-			}
-		}
-	};
+  methods: {
+    // getWindturbineFdc() {
+    //   api.getWindturbineFdc().then((res) => {
+    //     this.station = res.data;
+    //   });
+    // },
+    handleFaultClick(index) {
+      this.faultList = this.fault[index].alertSnaps;
+    },
+    handleClick(val) {
+      this.current = val;
+    },
+    getUniformCodes() {
+      api.getUniformCodes().then((res) => {
+        this.UniformCodes = res.data;
+      });
+    },
+    opened() {
+      this.line = "";
+      this.alarmTime = "";
+      this.alarmContent = "";
+      this.BasicInfo = this.uniformCodesDeal(this.windturbine);
+      this.BasicInfo.windturbineId = this.windturbine.windturbineId;
+      // this.dateDeal(this.BasicInfo)
+      this.$refs.BasicInfo.start(this.BasicInfo);
+      this.initData();
+      this.refreshData();
+      this.refreshTimer = setInterval(this.refreshData, 5000);
+    },
+    tableCellStyle({ row, column, rowIndex, columnIndex }) {
+      let warningColor = false;
+      let obj = {};
+      if (row.isOpened > 0) {
+        warningColor = true;
+      }
+      if (warningColor) {
+        obj = {
+          height: "40px",
+          background: "rgb(30,30,30)",
+          color: "#FF0000",
+          padding: "3px",
+          fontSize: "12px",
+          "border-top": "0px solid #000000",
+          "border-bottom": "1px solid #000000",
+          "border-right": "1px solid #000000",
+        };
+      } else {
+        obj = {
+          height: "40px",
+          background: "rgb(30,30,30)",
+          color: "rgb(220,220,220)",
+          padding: "3px",
+          fontSize: "12px",
+          "border-top": "0px solid #000000",
+          "border-bottom": "1px solid #000000",
+          "border-right": "1px solid #000000",
+        };
+      }
+
+      return obj;
+    },
+    uniformCodesDeal(windturbine) {
+      let val = this.UniformCodes[windturbine.stationId][windturbine.modelId];
+      let codes = "";
+      val.forEach((element) => {
+        element.param.forEach((itm) => {
+          codes += itm.code + ",";
+        });
+      });
+      val.codes = codes;
+      return val;
+    },
+    closed() {
+      this.$refs.BasicInfo.end();
+      this.$emit("close");
+      clearInterval(this.refreshTimer);
+      clearInterval(this.refreshTimers);
+      this.refreshTimers = null;
+      this.refreshTimer = null;
+    },
+    dateDeal(BasicInfo) {
+      let showInf = {};
+      showInf = BasicInfo.filter((item) => item.tag === "基本信息")[0];
+      this.baseDate.windSpeed = showInf.param.filter(
+        (item) => item.name === "风速"
+      )[0];
+      this.baseDate.power = showInf.param.filter(
+        (item) => item.name === "有功功率"
+      )[0];
+      this.baseDate.generatorSpeed = showInf.param.filter(
+        (item) => item.name === "发电机转速"
+      )[0];
+      this.baseDate.type = showInf.param.filter(
+        (item) => item.name === "状态"
+      )[0].value
+        ? this.typeList.filter(
+            (status) =>
+              status.type ===
+              Number(
+                showInf.param.filter((item) => item.name === "状态")[0].value
+              )
+          )[0].name
+        : "";
+      this.types = Number(
+        showInf.param.filter((item) => item.name === "状态")[0].value
+      );
+    },
+    refreshData() {
+      let bg = BackgroundData.getInstance();
+      bg.initWinturbineBaseData(this.BasicInfo, this.onMessage);
+      this.dateDeal(this.BasicInfo);
+      // clearInterval(this.refreshTimer);
+      // this.refreshTimers = setInterval(this.refreshData, 5000);
+    },
+    initData() {
+      api
+        .getWindWarning(this.windturbine.windturbineId, "1", "50")
+        .then((msg) => {
+          let vs = msg.data;
+          if (vs.length <= 0) return;
+          this.alarmTime = BackgroundData.getInstance().formatDate(
+            vs[0].lastUpdateTime
+          );
+          this.alarmContent = vs[0].alertText;
+          this.alarms = msg.data;
+          this.$refs.BasicInfo.alarmd(this.alarms);
+        })
+        .catch((err) => {
+          console.log(err);
+        });
+      api
+        .alarmSnap({
+          windturbineId: this.windturbine.windturbineId,
+        })
+        .then((res) => {
+          this.fault = res.data;
+          this.faultList = res.data[0].alertSnaps;
+          let faultNum = 0;
+          this.fault.forEach((item) => {
+            faultNum = faultNum + item.openedCount;
+          });
+          this.faultNum = faultNum;
+        });
+    },
+    dbClicks(value) {
+      this.$refs.BasicInfo.dbClicks(value, this.windturbine.windturbineId);
+    },
+    handleHealth(value) {
+      this.healthInfo = value;
+    },
+  },
+  watch: {
+    windturbine: {
+      handler: function (json) {
+        if (json) {
+          this.initData();
+        }
+      },
+    },
+  },
+};
 </script>
 <style scoped>
-	.my-info-dialog {
-		box-shadow: 0px 0px 10px #05bb4c;
-	}
+.my-info-dialog {
+  box-shadow: 0px 0px 10px #05bb4c;
+}
 
-	.body {
-		background-color: black;
-		margin-top: -30px;
-		margin-left: -10px;
-		margin-right: -10px;
-		margin-bottom: -30px;
-		border-bottom: 20px solid rgb(36, 36, 36);
-	}
+.body {
+  background-color: black;
+  margin-top: -30px;
+  margin-left: -10px;
+  margin-right: -10px;
+  margin-bottom: -30px;
+  border-bottom: 20px solid rgb(36, 36, 36);
+}
 
-	.chunkdiv {
-		display: flex;
-		flex-direction: row;
-		justify-content: center;
-		align-items: center;
-		width: 17%;
-		background-color: #363636;
-		margin: 1px;
-		padding: 4px 0px;
-		font-size: 12px;
-		color: #FFFFFF;
-		overflow: hidden;
-		white-space: nowrap;
-	}
+.chunkdiv {
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+  width: 17%;
+  background-color: #363636;
+  margin: 1px;
+  padding: 4px 0px;
+  font-size: 12px;
+  color: #ffffff;
+  overflow: hidden;
+  white-space: nowrap;
+}
 
-	.title {
-		font-size: 12px;
-		color: #B3B3B3;
-	}
+.title {
+  font-size: 12px;
+  color: #b3b3b3;
+}
 
-	table {
-		margin-left: 2px;
-		margin-right: 2px;
-	}
+table {
+  margin-left: 2px;
+  margin-right: 2px;
+}
 
-	/* td {
+/* td {
 		width: 20%;
 	} */
 
-	el-tabs {
-		background-color: black;
-	}
+el-tabs {
+  background-color: black;
+}
+
+.svg {
+  height: 67vh;
+}
+.titleList {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+}
+.faultInfo {
+  height: 70vh;
+  display: flex;
+  flex-direction: row;
+  width: 100%;
+}
+.left-item {
+  width: 16%;
+  background-color: #4d4d4d;
+  display: flex;
+  flex-direction: column;
+  padding-top: 20px;
+  align-items: center;
+  height: 96%;
+  overflow-y: auto;
+}
+.faultName {
+  font-size: 16px;
+  color: #ffffff;
+  margin-bottom: 10px;
+}
+.faultNameErr {
+  display: flex;
+  flex-direction: row;
+  align-items: baseline;
+  font-size: 16px;
+  color: red;
+  margin-bottom: 15px;
+}
+.faultNum {
+  font-size: 12px;
+}
+.right-item {
+  width: 83%;
+  background-color: #4d4d4d;
+  margin-left: 15px;
+  height: 96%;
+  padding-bottom: 20px;
+}
+.el-table {
+  background-color: #000000 !important;
+}
+.el-table__body-wrapper::-webkit-scrollbar {
+  width: 8px !important;
+  height: 0px !important;
+  background-color: black !important;
+}
 
-	.svg {
-		height: 67vh;
-	}
-	.titleList{
-		display: flex;
-		flex-direction: row;
-		align-items: center;
-	}
+.el-table__body-wrapper::-webkit-scrollbar-thumb {
+  background-color: #292929 !important;
+  border-radius: 6px !important;
+}
+.tables {
+  width: 98%;
+  margin: 1%;
+}
 </style>

Diferenças do arquivo suprimidas por serem muito extensas
+ 1165 - 0
src/components/allMatrices.vue


+ 454 - 396
src/components/basicDataDetails.vue

@@ -1,438 +1,496 @@
 <template>
-    <el-dialog width="50%" @closed="closed()" :show-close="false" class="my-info-dialog">
-        <template #title>
-            <div class="showTitles">
-                <div class="titles">{{partsName}}详情</div>
-                <div class="model">
-                    <div class="selects" v-show="!switchFlag">
-                        <!-- filterable allow-create default-first-option -->
-                        <el-select @change="search()" class="inputs" v-model="selectValue" placeholder="请选择">
-                            <el-option v-for="item in options" :key="item.value" :label="item.label"
-                                :value="item.value">
-                            </el-option>
-                        </el-select>
-                    </div>
-                    <div class="choose">
-                        <div :class="switchFlag?'interval':'interval_on'" @click="switchChange">等间隔</div>
-                        <div :class="switchFlag?'original_on':'original'" @click="switchChange">原始数据</div>
-                    </div>
-                </div>
+  <el-dialog
+    width="50%"
+    @closed="closed()"
+    :show-close="false"
+    class="my-info-dialog"
+  >
+    <template #title>
+      <div class="showTitles">
+        <div class="titles">{{ partsName }}详情</div>
+        <div class="model">
+          <div class="selects" v-show="!switchFlag">
+            <el-select
+              @change="search()"
+              class="inputs"
+              v-model="selectValue"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+          </div>
+          <div class="choose">
+            <div
+              :class="switchFlag ? 'interval' : 'interval_on'"
+              @click="switchChange"
+            >
+              等间隔
             </div>
-        </template>
-        <div class="bodys">
-            <div class="dataTitle">
-                <div class="operate">
-                    <el-date-picker class="picker" @change="changes" v-model="timeValue" type="datetimerange"
-                        range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
-                    </el-date-picker>
-                    <div class="buttons" @click="search()">查询</div>
-                </div>
-                <div class="buttons" @click="search('flag')">导出</div>
+            <div
+              :class="switchFlag ? 'original_on' : 'original'"
+              @click="switchChange"
+            >
+              原始数据
             </div>
-            <div :id="echartsId" class="showEcharts"></div>
+          </div>
         </div>
-    </el-dialog>
+      </div>
+    </template>
+    <div class="bodys">
+       <div class="dataTitle">
+        <div class="operate">
+          <el-date-picker
+            class="picker"
+            @change="changes"
+            v-model="timeValue"
+            type="datetimerange"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+          >
+          </el-date-picker>
+          <div class="buttons" @click="search()">查询</div>
+        </div>
+        <div class="buttons" @click="search('flag')">导出</div>
+      </div>
+      <div :id="echartsId" class="showEcharts"></div> 
+    </div>
+  </el-dialog>
 </template>
 <script>
-    import * as echarts from "echarts";
-    import dayjs from 'dayjs'
-    import XLSX from 'xlsx'
-    export default {
-        props: {
-            datas: {
-                type: Array,
-                default: () => {
-                    return []
-                },
-            },
-            partsName: Object,
-            echartsId: Object,
+import * as echarts from "echarts";
+import dayjs from "dayjs";
+import XLSX from "xlsx";
+export default {
+  props: {
+    datas: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    partsName: Object,
+    echartsId: Object,
+    calc: {
+      type: Number,
+      default: 1
+    },
+  },
+  updated() {
+    if (this.timeValue.length === 0) {
+      let date = new Date();
+      this.timeValue[0] = date.getTime() - 28800000;
+      this.timeValue[1] = date.getTime();
+    }
+    this.chooseTime = this.timeValue;
+    this.xdata = [];
+    this.values = [];
+    if (this.timeValue[1] - this.timeValue[0] <= 86400000) {
+      this.datas.map((item) => {
+        this.xdata.push(dayjs(item.ts).format("HH:mm"));
+        this.values.push(
+          item.doubleValue
+            ? (item.doubleValue * this.calc).toFixed(2)
+            : item.doubleValue === 0
+            ? item.doubleValue
+            : item.longValue * this.calc
+        );
+      });
+    } else {
+      this.datas.map((item) => {
+        this.xdata.push(dayjs(item.ts).format("MM-DD HH:mm"));
+        this.values.push(
+          item.doubleValue
+            ? (item.doubleValue * this.calc).toFixed(2)
+            : item.doubleValue === 0
+            ? item.doubleValue
+            : item.longValue * this.calc
+        );
+      });
+    }
+    this.$nextTick(() => {
+      this.getEcharts();
+    });
+  },
+  mounted() {},
+  data() {
+    return {
+      xdata: [],
+      values: [],
+      timeValue: [],
+      chooseTime: [],
+      switchFlag: false,
+      selectValue: "60",
+      options: [
+        {
+          value: "60",
+          label: "一分钟",
         },
-        updated() {
-            if (this.timeValue.length === 0) {
-                let date = new Date()
-                this.timeValue[0] = date.getTime() - 28800000
-                this.timeValue[1] = date.getTime()
-            }
-            this.chooseTime = this.timeValue
-            this.xdata = []
-            this.values = []
-            if ((this.timeValue[1] - this.timeValue[0]) <= 86400000) {
-                this.datas.map(item => {
-                    this.xdata.push(dayjs(item.ts).format('HH:mm'))
-                    this.values.push(item.doubleValue ? item.doubleValue.toFixed(2) : item.doubleValue === 0 ? item.doubleValue : item.longValue)
-                })
-                console.log(this.values)
-            } else {
-                this.datas.map(item => {
-                    this.xdata.push(dayjs(item.ts).format('MM-DD HH:mm'))
-                    this.values.push(item.doubleValue ? item.doubleValue.toFixed(2) : item.doubleValue === 0 ? item.doubleValue : item.longValue)
-                })
-            }
-            this.getEcharts()
+        {
+          value: "300",
+          label: "五分钟",
         },
-        mounted() {
-
+        {
+          value: "600",
+          label: "十分钟",
         },
-        data() {
-            return {
-                xdata: [],
-                values: [],
-                timeValue: [],
-                chooseTime: [],
-                switchFlag: false,
-                selectValue: '60',
-                options: [{
-                    value: '60',
-                    label: '一分钟'
-                }, {
-                    value: '300',
-                    label: '五分钟'
-                }, {
-                    value: '600',
-                    label: '十分钟'
-                }, {
-                    value: '1800',
-                    label: '三十分钟'
-                }, {
-                    value: '3600',
-                    label: '一小时'
-                }, {
-                    value: '86400',
-                    label: '一天'
-                }],
-            }
+        {
+          value: "1800",
+          label: "三十分钟",
         },
-        methods: {
-            changes() {
-                let timeValue = []
-                this.timeValue?.forEach(item => {
-                    timeValue.push(dayjs(item).valueOf())
-                })
-                this.chooseTime = timeValue
-            },
-            switchChange() {
-                this.switchFlag = !this.switchFlag
-                this.selectValue = '60'
-                this.search();
-                const loading = this.$loading({
-                    lock: true,
-                    text: '数据加载中',
-                    spinner: 'el-icon-loading',
-                    background: 'rgba(0, 0, 0, 0.7)'
-                });
-                setTimeout(() => {
-                    loading.close();
-                }, 1000);
-            },
-            search(values) {
-                let times = []
-                this.chooseTime.forEach(item => {
-                    times.push(dayjs(item).valueOf())
-                })
-                times.length > 0 ?
-                    this.switchFlag ? this.$emit('original-data', times) : this.$emit('search-data', times, Number(this.selectValue))
-                    :
-                    this.$message({
-                        showClose: true,
-                        message: '请选择查询日期',
-                        center: true,
-                        type: 'error'
-                    });
-                if (values) {
-                    this.$message({
-                        showClose: true,
-                        center: true,
-                        message: '下载中'
-                    });
-                    setTimeout(() => {
-                        this.export()
-                    }, 2000)
-                }
-            },
-            export() {
-                // 数据源
-                let data = []
-                this.datas.forEach(item => {
-                    let values = {
-                        '时间': dayjs(item.ts).format('MM-DD HH:mm:ss'),
-                        '数值': item.doubleValue,
-                    }
-                    data.push(values)
-                })
-                // 下载的路径
-                let fileName = `${this.partsName}.xlsx`
-                let filePath = '/root/' + fileName
-                // 新建workbook
-                const wb = XLSX.utils.book_new()
-                // 新建worksheet,并载入数据
-                const ws = XLSX.utils.json_to_sheet(data)
-                // 设置每列的列宽,10代表10个字符,注意中文占2个字符
-                ws['!cols'] = [
-                    { wch: 30 },
-                    { wch: 30 },
-                ]
-                // 生成xlsx文件(workbook,worksheet数据,sheet命名)
-                XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
+        {
+          value: "3600",
+          label: "一小时",
+        },
+        {
+          value: "86400",
+          label: "一天",
+        },
+      ],
+    };
+  },
+  methods: {
+    changes() {
+      let timeValue = [];
+      this.timeValue?.forEach((item) => {
+        timeValue.push(dayjs(item).valueOf());
+      });
+      this.chooseTime = timeValue;
+    },
+    switchChange() {
+      this.switchFlag = !this.switchFlag;
+      this.selectValue = "60";
+      this.search();
+      const loading = this.$loading({
+        lock: true,
+        text: "数据加载中",
+        spinner: "el-icon-loading",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+      setTimeout(() => {
+        loading.close();
+      }, 1000);
+    },
+    search(values) {
+      let times = [];
+      this.chooseTime.forEach((item) => {
+        times.push(dayjs(item).valueOf());
+      });
+      times.length > 0
+        ? this.switchFlag
+          ? this.$emit("original-data", times)
+          : this.$emit("search-data", times, Number(this.selectValue))
+        : this.$message({
+            showClose: true,
+            message: "请选择查询日期",
+            center: true,
+            type: "error",
+          });
+      if (values) {
+        this.$message({
+          showClose: true,
+          center: true,
+          message: "下载中",
+        });
+        setTimeout(() => {
+          this.export();
+        }, 2000);
+      }
+    },
+    export() {
+      // 数据源
+      let data = [];
+      this.datas.forEach((item) => {
+        let values = {
+          时间: dayjs(item.ts).format("MM-DD HH:mm:ss"),
+          数值: item.doubleValue,
+        };
+        data.push(values);
+      });
+      // 下载的路径
+      let fileName = `${this.partsName}.xlsx`;
+      let filePath = "/root/" + fileName;
+      // 新建workbook
+      const wb = XLSX.utils.book_new();
+      // 新建worksheet,并载入数据
+      const ws = XLSX.utils.json_to_sheet(data);
+      // 设置每列的列宽,10代表10个字符,注意中文占2个字符
+      ws["!cols"] = [{ wch: 30 }, { wch: 30 }];
+      // 生成xlsx文件(workbook,worksheet数据,sheet命名)
+      XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
 
-                // 写文件(workbook,xlsx文件路径+文件名)
-                XLSX.writeFile(wb, filePath)
-                this.$message({
-                    showClose: true,
-                    message: '下载成功',
-                    center: true,
-                    type: 'success'
-                });
+      // 写文件(workbook,xlsx文件路径+文件名)
+      XLSX.writeFile(wb, filePath);
+      this.$message({
+        showClose: true,
+        message: "下载成功",
+        center: true,
+        type: "success",
+      });
+    },
+    getEcharts() {
+      let chartDom = document.getElementById(this.echartsId);
+      let myChart = echarts.init(chartDom, "#ffffff");
+      let option;
+      option = {
+        tooltip: {
+          trigger: 'axis'
+        },
+        legend: {
+          show: true,
+          data: [this.partsName],
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: "#606769",
+          textStyle: {
+            color: "#B3BDC0",
+            fontSize: 12,
+          },
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              interval:
+                Number((this.xdata.length / 8).toFixed(0)) > 2
+                  ? Number((this.xdata.length / 8).toFixed(0))
+                  : 0,
+              showMinLabel: true,
+              showMaxLabel: true,
+              formatter: "{value}",
+              fontSize: 14,
+              textStyle: {
+                color: "#606769",
+              },
             },
-            getEcharts() {
-                let chartDom = document.getElementById(this.echartsId);
-                let myChart = echarts.init(chartDom, '#ffffff');
-                let option;
-                option = {
-                    legend: {
-                        show: true,
-                        data: [this.partsName],
-                        right: 56,
-                        icon: "circle",
-                        itemWidth: 6,
-                        inactiveColor: '#606769',
-                        textStyle: {
-                            color: '#B3BDC0',
-                            fontSize: 12,
-                        },
-                    },
-                    xAxis: [
-                        {
-                            type: "category",
-                            boundaryGap: false,
-                            axisLabel: {
-                                interval: (Number((this.xdata.length / 8).toFixed(0)) > 2) ? Number((this.xdata.length / 8).toFixed(0)) : 0,
-                                showMinLabel: true,
-                                showMaxLabel: true,
-                                formatter: "{value}",
-                                fontSize: 14,
-                                textStyle: {
-                                    color: '#606769',
-                                },
-                            },
-                            axisLine: {
-                                show: false,
-                            },
-                            data: this.xdata,
-                        },
-                    ],
-                    yAxis: {
-                        type: "value",
-                        axisLabel: {
-                            formatter: "{value}",
-                            fontSize: 14,
-                        },
-                        axisLine: {
-                            show: false,
-                        },
-                        splitLine: {
-                            show: true,
-                            lineStyle: {
-                                color: '#606769',
-                                type: "dashed",
-                            },
-                        },
-                    },
-                    series: [{
-                        // name: this.partsName,
-                        smooth: true,
-                        showSymbol: false,
-                        data: this.values,
-                        type: 'line'
-                    }]
-                };
-                option && myChart.setOption(option);
+            axisLine: {
+              show: false,
             },
-            closed() {
-                this.chooseTime = []
-                this.timeValue = []
-                this.switchFlag = false
-                this.selectValue = '60'
-                this.$emit('closed');
+            data: this.xdata,
+          },
+        ],
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: 14,
+          },
+          axisLine: {
+            show: false,
+          },
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "#606769",
+              type: "dashed",
             },
+          },
         },
-    }
+        series: [
+          {
+            // name: this.partsName,
+            smooth: true,
+            showSymbol: false,
+            data: this.values,
+            type: "line",
+          },
+        ],
+      };
+      option && myChart.setOption(option);
+    },
+    closed() {
+      this.chooseTime = [];
+      this.timeValue = [];
+      this.switchFlag = false;
+      this.selectValue = "60";
+      this.$emit("closed");
+    },
+  },
+};
 </script>
 
 <style>
-    .showTitles {
-        display: flex;
-        flex-direction: row;
-        align-items: center;
-        justify-content: space-between;
-        margin-top: -10px;
-        font-size: 18px;
-        color: #FFFFFF;
-        height: 40px;
-    }
+.showTitles {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  margin-top: -10px;
+  font-size: 18px;
+  color: #ffffff;
+  height: 40px;
+}
 
-    .titles {
-        font-size: 16px;
-        color: #FFFFFF;
-    }
+.titles {
+  font-size: 16px;
+  color: #ffffff;
+}
 
-    .el-dialog__body {
-        padding: 30px 10px 10px 10px;
-    }
+.el-dialog__body {
+  padding: 30px 10px 10px 10px;
+}
 
-    .bodys {
-        display: flex;
-        flex-direction: column;
-        align-items: center;
-        background-color: black;
-        width: 100%;
-        margin-top: -30px;
-    }
+.bodys {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  background-color: black;
+  width: 100%;
+  margin-top: -30px;
+}
 
-    .showEcharts {
-        width: 1030px;
-        height: 480px;
-        margin-left: 30px;
-        /* padding-top: 20px; */
-    }
+.showEcharts {
+  width: 1030px;
+  height: 480px;
+  margin-left: 30px;
+  /* padding-top: 20px; */
+}
 
-    .dataTitle {
-        width: 100%;
-        display: flex;
-        flex-direction: row;
-        align-items: center;
-        justify-content: space-between;
-        margin-top: 10px;
-    }
+.dataTitle {
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  margin-top: 10px;
+}
 
-    .picker {
-        margin-left: 20px;
-        margin-right: 16px;
-    }
+.picker {
+  margin-left: 20px;
+  margin-right: 16px;
+}
 
-    .el-date-editor .el-range-input {
-        background-color: rgba(26, 26, 26, 1) !important;
-        border: none;
-        color: #ffffff !important;
-    }
+.el-date-editor .el-range-input {
+  background-color: rgba(26, 26, 26, 1) !important;
+  border: none;
+  color: #ffffff !important;
+}
 
-    .el-input__inner {
-        background-color: rgba(26, 26, 26, 1) !important;
-    }
+.el-input__inner {
+  background-color: rgba(26, 26, 26, 1) !important;
+}
 
-    .el-date-editor .el-range-separator {
-        color: #ffffff !important;
-    }
+.el-date-editor .el-range-separator {
+  color: #ffffff !important;
+}
 
-    .el-date-table td.in-range div,
-    .el-date-table td.in-range div:hover,
-    .el-date-table.is-week-mode .el-date-table__row.current div,
-    .el-date-table.is-week-mode .el-date-table__row:hover div {
-        background-color: #CECEFF !important;
-    }
+.el-date-table td.in-range div,
+.el-date-table td.in-range div:hover,
+.el-date-table.is-week-mode .el-date-table__row.current div,
+.el-date-table.is-week-mode .el-date-table__row:hover div {
+  background-color: #ceceff !important;
+}
 
-    .operate {
-        display: flex;
-        flex-direction: row;
-        align-items: center;
-        justify-content: center;
-        /* margin-right: 65px; */
-    }
+.operate {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  /* margin-right: 65px; */
+}
 
-    .buttons {
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        width: 100px;
-        height: 40px;
-        background-color: rgba(26, 26, 26, 1);
-        border: 1px solid rgba(77, 77, 77, 1);
-        color: #ffffff;
-        margin-right: 28px;
-        font-size: 12px;
-    }
+.buttons {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100px;
+  height: 40px;
+  background-color: rgba(26, 26, 26, 1);
+  border: 1px solid rgba(77, 77, 77, 1);
+  color: #ffffff;
+  margin-right: 28px;
+  font-size: 12px;
+}
 
-    .model {
-        display: flex;
-        flex-direction: row;
-        align-items: center;
-        color: rgba(240, 240, 240, 1);
-        font-size: 12px;
-    }
+.model {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  color: rgba(240, 240, 240, 1);
+  font-size: 12px;
+}
 
-    .el-switch {
-        width: 453px;
-    }
+.el-switch {
+  width: 453px;
+}
 
-    .el-switch__label {
-        color: #999999 !important;
-    }
+.el-switch__label {
+  color: #999999 !important;
+}
 
-    .el-switch__label.is-active {
-        color: rgba(37, 116, 219, 1) !important;
-    }
+.el-switch__label.is-active {
+  color: rgba(37, 116, 219, 1) !important;
+}
 
-    .selects {
-        margin-right: 16px;
-    }
+.selects {
+  margin-right: 16px;
+}
 
-    .choose {
-        width: 160px;
-        height: 25px;
-        display: flex;
-        flex-direction: row;
-        align-items: center;
-        color: #FFFFFF;
-    }
+.choose {
+  width: 160px;
+  height: 25px;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  color: #ffffff;
+}
 
-    .interval {
-        width: 50%;
-        height: 100%;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        border: 1px solid rgba(77, 77, 77, 1);
-        border-top-left-radius: 12.5px;
-        border-bottom-left-radius: 12.5px;
-    }
+.interval {
+  width: 50%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border: 1px solid rgba(77, 77, 77, 1);
+  border-top-left-radius: 12.5px;
+  border-bottom-left-radius: 12.5px;
+}
 
-    .interval_on {
-        width: 50%;
-        height: 100%;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        background-color: rgba(29, 106, 235, 1);
-        border: 1px solid rgba(29, 106, 235, 1);
-        border-top-left-radius: 12.5px;
-        border-bottom-left-radius: 12.5px;
-    }
+.interval_on {
+  width: 50%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: rgba(29, 106, 235, 1);
+  border: 1px solid rgba(29, 106, 235, 1);
+  border-top-left-radius: 12.5px;
+  border-bottom-left-radius: 12.5px;
+}
 
-    .original {
-        width: 50%;
-        height: 100%;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        border: 1px solid rgba(77, 77, 77, 1);
-        border-top-right-radius: 12.5px;
-        border-bottom-right-radius: 12.5px;
-    }
+.original {
+  width: 50%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  border: 1px solid rgba(77, 77, 77, 1);
+  border-top-right-radius: 12.5px;
+  border-bottom-right-radius: 12.5px;
+}
 
-    .original_on {
-        width: 50%;
-        height: 100%;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        background-color: rgba(29, 106, 235, 1);
-        border: 1px solid rgba(29, 106, 235, 1);
-        border-top-right-radius: 12.5px;
-        border-bottom-right-radius: 12.5px;
-    }
+.original_on {
+  width: 50%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: rgba(29, 106, 235, 1);
+  border: 1px solid rgba(29, 106, 235, 1);
+  border-top-right-radius: 12.5px;
+  border-bottom-right-radius: 12.5px;
+}
 
-    .inputs {
-        border: none;
-        width: 110px !important;
-    }
+.inputs {
+  border: none;
+  width: 110px !important;
+}
 </style>

+ 200 - 170
src/components/boxSelect.vue

@@ -1,180 +1,210 @@
 <template>
-    <div class="box-select__container" @mousedown.left="mouseDown" @mousemove.stop="mouseMove" :class="uuid">
-        <div class="box-select__coordinate" :style="style" ref="selectContainer"></div>
-        <slot></slot>
-    </div>
+  <div
+    class="box-select__container"
+    @mousedown.left="mouseDown"
+    @mousemove.stop="mouseMove"
+    :class="uuid"
+  >
+    <div
+      class="box-select__coordinate"
+      :style="style"
+      ref="selectContainer"
+    ></div>
+    <slot></slot>
+  </div>
 </template>
 
 <script>
-    import { debounce, isNumber } from "lodash"
-    import { ref, onUnmounted, nextTick, shallowRef } from "vue"
-
-    /**
-     * @description 判断元素是否在范围内
-     * @param {Object} dom dom元素
-     */
-    const isWithinRange = (dom, top, bottom, left, right) => {
-        const eleRect = dom.getBoundingClientRect()
-        return !(
-            eleRect.top > bottom ||
-            eleRect.bottom < top ||
-            eleRect.right < left ||
-            eleRect.left > right
-        )
-    }
-
-    export default {
-        name: "BoxSelect",
-        /**
-         * @member props
-         * @property  {String} [node] 要框选的元素,可以是元素名,也可以是class名, 也可以是id名
-         * @property  {String} [selectedClass] 已选中元素附加的class名
-         */
-        props: {
-            node: {
-                required: true,
-                type: String
-            },
-            selectedClass: {
-                type: String,
-                default: 'box-select__hypocritical'
-            }
-        },
-        // 鼠标按下
-        emits: ["mouseUp", "mouseDown"],
-        setup(props, { emit }) {
-            let top = 0,
-                left = 0,
-                width = 0,
-                height = 0,
-                startX = 0,
-                startY = 0,
-                timer = null,
-                // 记录是框选还是点击
-                mouseOn = false
-
-            const style = ref({}),
-                selectContainer = ref(null),
-                // 给当前框容器加一个唯一识别符, 以保证所选择到的元素都是当前容器的. 否则会选择到容器外同名的元素
-                uuid = shallowRef("uuid_" + new Date().valueOf())
-
-            const query = (className = '') => {
-                let domName = `.${uuid.value} ${props.node}`
-                className && (domName += `.${className}`)
-                return Array.from(document.querySelectorAll(domName) || [])
-            }
-
-            const classOperation = (ele, method = 'add', className = '') => ele.classList[method](className)
-
-            const setStyle = (styles = {}, newStyles = {}) => {
-                Object.keys(styles).map((item) => {
-                    newStyles[item] = styles[item] + (isNumber(styles[item]) ? "px" : '')
-                })
-                style.value = newStyles
-            }
-
-            const getAreaWithinElements = () => {
-                const {
-                    bottom,
-                    left,
-                    right,
-                    top
-                } = selectContainer.value.getBoundingClientRect()
-
-                // 所有可框选元素
-                const elements = query()
-                // 已选中元素
-                const selectedElements = elements.filter(item => classOperation(item, 'contains', props.selectedClass))
-                // 未选中元素
-                const unselectedElements = elements.filter(item => !classOperation(item, 'contains', props.selectedClass))
-
-                selectedElements.map(item => {
-                    const withinRange = isWithinRange(item, top, bottom, left, right)
-                    withinRange &&
-                        classOperation(item, 'contains', props.selectedClass) &&
-                        classOperation(item, 'remove', props.selectedClass)
-                })
-
-                unselectedElements.map((item) =>
-                    isWithinRange(item, top, bottom, left, right) &&
-                    classOperation(item, 'add', props.selectedClass))
-
-                return query(props.selectedClass)
-            }
-
-            const mouseDown = debounce((event) => {
-                timer = setTimeout(() => {
-                    mouseOn = true
-                    startX = event.clientX
-                    startY = event.clientY
-                    emit("mouseDown")
-                }, 300)
-                // 重置本次框选的元素列表
-                setStyle({ left, startX, top: startY, width: 0, height: 0, display: "block" })
-            })
-
-            const mouseMove = debounce((event) => {
-                if (!mouseOn) return false
-                const _width = event.clientX - startX
-                const _height = event.clientY - startY
-
-                top = _height > 0 ? startY : event.clientY
-                left = _width > 0 ? startX : event.clientX
-                width = Math.abs(_width)
-                height = Math.abs(_height)
-                setStyle({ left, top, width, height })
-            })
-
-            const mouseUp = debounce((event) => {
-                timer && clearTimeout(timer)
-                // 判断是否鼠标左键
-                if (event.which !== 1) return false
-                // 判断是框选还是点击
-                if (!mouseOn) return false
-                mouseOn = false
-                setStyle({ display: "none" })
-                // 获得已选中的元素
-                const selectedEles = getAreaWithinElements()
-                // 响应事件,并传递本次框选的元素列表
-                emit("mouseUp", selectedEles)
-            })
-
-            nextTick(() => document.addEventListener("mouseup", mouseUp))
-            onUnmounted(() => document.removeEventListener("mouseup", mouseUp))
-
-            return {
-                mouseUp,
-                mouseDown,
-                mouseMove,
-                timer,
-                style,
-                selectContainer,
-                uuid
+import { debounce, isNumber } from "lodash";
+import { ref, onUnmounted, nextTick, shallowRef } from "vue";
+
+/**
+ * @description 判断元素是否在范围内
+ * @param {Object} dom dom元素
+ */
+const isWithinRange = (dom, top, bottom, left, right) => {
+  const eleRect = dom.getBoundingClientRect();
+  return !(
+    eleRect.top > bottom ||
+    eleRect.bottom < top ||
+    eleRect.right < left ||
+    eleRect.left > right
+  );
+};
+
+export default {
+  name: "BoxSelect",
+  /**
+   * @member props
+   * @property  {String} [node] 要框选的元素,可以是元素名,也可以是class名, 也可以是id名
+   * @property  {String} [selectedClass] 已选中元素附加的class名
+   */
+  props: {
+    node: {
+      required: true,
+      type: String,
+    },
+    selectedClass: {
+      type: String,
+      default: "box-select__hypocritical",
+    },
+  },
+  // 鼠标按下
+  emits: ["mouseUp", "mouseDown"],
+  setup(props, { emit }) {
+    let top = 0,
+      left = 0,
+      width = 0,
+      height = 0,
+      startX = 0,
+      startY = 0,
+      timer = null,
+      // 记录是框选还是点击
+      mouseOn = false;
+
+    const style = ref({}),
+      selectContainer = ref(null),
+      // 给当前框容器加一个唯一识别符, 以保证所选择到的元素都是当前容器的. 否则会选择到容器外同名的元素
+      uuid = shallowRef("uuid_" + new Date().valueOf());
+
+    const query = (className = "") => {
+      let domName = `.${uuid.value} ${props.node}`;
+      className && (domName += `.${className}`);
+      return Array.from(document.querySelectorAll(domName) || []);
+    };
+
+    const classOperation = (ele, method = "add", className = "") =>
+      ele.classList[method](className);
+
+    const setStyle = (styles = {}, newStyles = {}) => {
+      Object.keys(styles).map((item) => {
+        newStyles[item] = styles[item] + (isNumber(styles[item]) ? "px" : "");
+      });
+      style.value = newStyles;
+    };
+
+    const getAreaWithinElements = () => {
+      const { bottom, left, right, top } =
+        selectContainer.value.getBoundingClientRect();
+
+      // 所有可框选元素
+      const elements = query();
+      // // 已选中元素
+      // const selectedElements = elements.filter((item) =>
+      //   classOperation(item, "contains", props.selectedClass)
+      // );
+      // // 未选中元素
+      // const unselectedElements = elements.filter(
+      //   (item) => !classOperation(item, "contains", props.selectedClass)
+      // );
+      // 本次框选元素
+      let selctList = []
+      for (const key in elements) {
+        for (const i in elements[key].children) {
+          if(Number(i) || i === '0'){
+            let val = elements[key].children[i]
+            const withinRange = isWithinRange(val, top, bottom, left, right);
+            if(withinRange){
+                selctList.push(val)
             }
+          }
         }
-    }
+      }
+        
+      emit('selectList', selctList);
+      // selectedElements.map((item) => {
+      //     const withinRange = isWithinRange(item, top, bottom, left, right);
+      //     withinRange &&
+      //       classOperation(item, "add", props.selectedClass)
+      //   });
+      //   unselectedElements.map(
+      //     (item) =>
+      //       isWithinRange(item, top, bottom, left, right) &&
+      //       classOperation(item, "add", props.selectedClass)
+      //   );
+
+      // return query(props.selectedClass);
+    };
+
+    const mouseDown = debounce((event) => {
+      timer = setTimeout(() => {
+        mouseOn = true;
+        startX = event.clientX;
+        startY = event.clientY;
+        emit("mouseDown");
+      }, 300);
+      // 重置本次框选的元素列表
+      setStyle({
+        left,
+        startX,
+        top: startY,
+        width: 0,
+        height: 0,
+        display: "block",
+      });
+    });
+
+    const mouseMove = debounce((event) => {
+      if (!mouseOn) return false;
+      const _width = event.clientX - startX;
+      const _height = event.clientY - startY;
+
+      top = _height > 0 ? startY : event.clientY;
+      left = _width > 0 ? startX : event.clientX;
+      width = Math.abs(_width);
+      height = Math.abs(_height);
+      setStyle({ left, top, width, height });
+    });
+
+    const mouseUp = debounce((event) => {
+      timer && clearTimeout(timer);
+      // 判断是否鼠标左键
+      if (event.which !== 1) return false;
+      // 判断是框选还是点击
+      if (!mouseOn) return false;
+      mouseOn = false;
+      setStyle({ display: "none" });
+      // 获得已选中的元素
+      const selectedEles = getAreaWithinElements();
+      // 响应事件,并传递本次框选的元素列表
+      emit("mouseUp", selectedEles);
+    });
+
+    nextTick(() => document.addEventListener("mouseup", mouseUp));
+    onUnmounted(() => document.removeEventListener("mouseup", mouseUp));
+
+    return {
+      mouseUp,
+      mouseDown,
+      mouseMove,
+      timer,
+      style,
+      selectContainer,
+      uuid,
+    };
+  },
+};
 </script>
 
 <style lang="scss">
-    .box-select__container {
-        background-color: #ffffff;
-        height: 50vh;
-    }
-
-    .box-select__coordinate {
-        position: fixed;
-        z-index: 11;
-        left: 0;
-        top: 0;
-        width: 0;
-        height: 0;
-        background: rgba(0, 0, 0, .5);
-        border: 1px solid rgba(0, 0, 0, 1);
-        opacity: 0.6;
-        pointer-events: none;
-    }
-
-    .box-select__hypocritical {
-        background-color: blue;
-    }
+.box-select__container {
+  // height: 50vh;
+}
+
+.box-select__coordinate {
+  position: fixed;
+  z-index: 11;
+  left: 0;
+  top: 0;
+  width: 0;
+  height: 0;
+  background: rgba(106, 90, 205,.5);
+  border: 1px solid blue;
+  opacity: 0.6;
+  pointer-events: none;
+}
+
+.box-select__hypocritical {
+  background-color: blue;
+}
 </style>

+ 171 - 157
src/components/check/areaCard.vue

@@ -1,6 +1,6 @@
 /* 自定义tabs */
 <template>
-    <!-- <transition>
+  <!-- <transition>
         <div :class='areaClass' @mouseover="hover = false" @mouseleave="hover = false" onselectstart="return false">
             <div :class="headerClass">
                 <div :class='circleClass'></div>
@@ -15,172 +15,186 @@
             </div>
         </div>
     </transition> -->
-    <div class="body">
-        <img class="logo" src="../../assets/img/logo.png" alt="">
-        <div class="title">{{ title }}</div>
-        <div class="record" @click="showRecord">校验记录</div>
-        <div style="margin-top: 50px; margin-left: 20px; height: 80%;">
-            <el-scrollbar>
-                <div class="scoll" style="margin-left: 5px;">
-                    <MatrixBlock  @on-click="handleClick" :dataList="showList"></MatrixBlock>
-                </div>
-            </el-scrollbar>
+  <div class="body">
+    <img class="logo" src="../../assets/img/logo.png" alt="" />
+    <div class="title">{{ title }}</div>
+    <!-- <div class="record" @click="showRecord">校验记录</div> -->
+    <div style="margin-top: 50px; margin-left: 20px; height: 80%">
+      <el-scrollbar>
+        <div class="scoll" style="margin-left: 5px">
+          <MatrixBlock
+            @on-click="handleClick"
+            :dataList="showList"
+          ></MatrixBlock>
         </div>
-        <OperationRecords ref="records" v-model="display" @closed="closed()"></OperationRecords>
-        <WindturbineDetailPages v-model="dialogVisible" @close="handleClose" :windturbine="currentWindturbine">
-    </WindturbineDetailPages>
+      </el-scrollbar>
     </div>
+    <OperationRecords
+      ref="records"
+      v-model="display"
+      @closed="closed()"
+    ></OperationRecords>
+    <WindturbineDetailPages
+      v-model="dialogVisible"
+      @close="handleClose"
+      :windturbine="currentWindturbine"
+    >
+    </WindturbineDetailPages>
+  </div>
 </template>
 
 <script>
-    import BackgroundData from 'utils/BackgroundData'
-    import MatrixBlock from "../matrixBlock.vue";
-    import OperationRecords from "./operationRecords.vue";
-    import WindturbineDetailPages from "../WindturbineDetailPages.vue";
-    export default {
-        props: {
-            title: {
-                type: String,
-                default: '校验区',
-                required: true
-            },
-            height: {
-                type: Number,
-                default: 200,
-            },
-        },
-        components: {
-            MatrixBlock,
-            OperationRecords,
-            WindturbineDetailPages
-        },
-        data() {
-            return {
-                showList: [],
-                arr: [],
-                list: [],
-                display:false,
-                dialogVisible:false,
-                currentWindturbine: {},
-            }
-        },
-        methods: {
-            dataDeal() {
-                let flag = false
-                let showList = []
-                let arr = []
-                let checks = BackgroundData.getInstance().checkouts;
-                checks.forEach(item => {
-                    if (item.status === this.list[item.windturbineId].status) {
-                        showList.push(this.list[item.windturbineId])
-                    } else {
-                        BackgroundData.getInstance().removeCheckouts(item);
-                    }
-                    if ((new Date()).getTime() - item.checkTime > 120000) {
-                        BackgroundData.getInstance().removeCheckouts(item);
-                        arr.push(item.windturbineId)
-                        flag = true
-                    }
-                })
-                this.showList = showList
-                if (flag) {
-                    let mss = arr.join(',') + '风机超时未响应,已移除'
-                    this.$notify({
-                        title: "控制",
-                        message: mss,
-                        type: "warning",
-                        position: "bottom-right",
-                        offset: 60,
-                        duration: 3000,
-                    });
-                    flag = false
-                }
-            },
-            showRecord(){
-                this.display = true
-                this.$refs.records.dataDeal() 
-            },
-            closed(){
-                this.display = false
-            },
-            handleClick(itm) {
-                this.dialogVisible = true;
-                this.currentWindturbine = itm;
-            },
-            handleClose() {
-                this.dialogVisible = false
-            },
-        },
-        watch: {
-            "$store.getters.windturbinelist": {
-                deep: true,
-                handler: function (json) {
-                    this.list = json
-                    this.arr = BackgroundData.getInstance().checkouts;
-                    this.dataDeal()
-                },
-            },
-        },
-    }
+import BackgroundData from "utils/BackgroundData";
+import MatrixBlock from "../matrixBlock.vue";
+import OperationRecords from "./operationRecords.vue";
+import WindturbineDetailPages from "../WindturbineDetailPages.vue";
+export default {
+  props: {
+    title: {
+      type: String,
+      default: "校验区",
+      required: true,
+    },
+    height: {
+      type: Number,
+      default: 200,
+    },
+  },
+  components: {
+    MatrixBlock,
+    OperationRecords,
+    WindturbineDetailPages,
+  },
+  data() {
+    return {
+      showList: [],
+      arr: [],
+      display: false,
+      dialogVisible: false,
+      currentWindturbine: {},
+      intervals: null,
+    };
+  },
+  created() {
+    this.dataDeal();
+    this.intervals = setInterval(this.dataDeal, 1000);
+    this.arr = BackgroundData.getInstance().checkouts;
+  },
+  methods: {
+    dataDeal() {
+      if (this.arr.length > 0) {
+        let flag = false;
+        let showList = [];
+        let arr = [];
+        let checks = BackgroundData.getInstance().checkouts;
+        checks.forEach((item) => {
+          if (item.status === this.$store.state.windturbinelist[item.windturbineId].status) {
+            showList.push(this.$store.state.windturbinelist[item.windturbineId]);
+          } else {
+            BackgroundData.getInstance().removeCheckouts(item);
+          }
+          if (new Date().getTime() - item.checkTime > 120000) {
+            BackgroundData.getInstance().removeCheckouts(item);
+            arr.push(item.windturbineId);
+            flag = true;
+          }
+        });
+        this.showList = showList;
+        if (flag) {
+          let mss = arr.join(",") + "风机超时未响应,已移除";
+          this.$notify({
+            title: "控制",
+            message: mss,
+            type: "warning",
+            position: "bottom-right",
+            offset: 60,
+            duration: 3000,
+          });
+          flag = false;
+        }
+      }else{
+        this.showList = [];
+      }
+    },
+    showRecord() {
+      this.display = true;
+      this.$refs.records.dataDeal();
+    },
+    closed() {
+      this.display = false;
+    },
+    handleClick(itm) {
+      this.dialogVisible = true;
+      this.currentWindturbine = itm;
+    },
+    handleClose() {
+      this.dialogVisible = false;
+    },
+  },
+  unmounted() {
+    clearInterval(this.intervals);
+    this.intervals = null;
+  },
+};
 </script>
 
 <style scoped="scoped">
-    .body {
-        border: 1px solid #373737;
-        width: 100%;
-        margin-left: 15px;
-        margin-top: 10px;
-        height: 25vh;
-    }
+.body {
+  border: 1px solid #373737;
+  width: 100%;
+  margin-left: 15px;
+  margin-top: 10px;
+  height: 25vh;
+}
 
-    .body .scoll {
-        height: 91%;
-    }
+.body .scoll {
+  height: 91%;
+}
 
-    .title {
-        color: #ffffff;
-        font-size: 14px;
-        margin-left: 32px;
-        /* margin-top: 12px; */
-        margin-bottom: 10px;
-        /* width: 570px; */
-        width: 29vw;
-        height: 50px;
-        display: flex;
-        align-items: center;
-        position: absolute;
-        background-color: #000000;
-    }
+.title {
+  color: #ffffff;
+  font-size: 14px;
+  margin-left: 32px;
+  /* margin-top: 12px; */
+  margin-bottom: 10px;
+  /* width: 570px; */
+  width: 29vw;
+  height: 50px;
+  display: flex;
+  align-items: center;
+  position: absolute;
+  background-color: #000000;
+}
 
-    .title::before {
-        z-index: 1;
-        content: '';
-        position: absolute;
-        left: -18px !important;
-        /* top: 30px !important; */
-        width: 5px;
-        height: 5px;
-        background-color: #54B75A;
-        border-radius: 50%;
-    }
+.title::before {
+  z-index: 1;
+  content: "";
+  position: absolute;
+  left: -18px !important;
+  /* top: 30px !important; */
+  width: 5px;
+  height: 5px;
+  background-color: #54b75a;
+  border-radius: 50%;
+}
 
-    .record {
-        position: absolute;
-        color: #ffffff;
-        font-size: 14px;
-        right: 0;
-        top: 23px;
-        width: 80px;
-        height: 30px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        background-color: rgba(37, 116, 219, 1);
-    }
+.record {
+  position: absolute;
+  color: #ffffff;
+  font-size: 14px;
+  right: 0;
+  top: 23px;
+  width: 80px;
+  height: 30px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: rgba(37, 116, 219, 1);
+}
 
-    .logo {
-        position: absolute;
-        top: 2px;
-        left: 12px;
-    }
-</style>
+.logo {
+  position: absolute;
+  top: 2px;
+  left: 12px;
+}
+</style>

+ 379 - 362
src/components/check/operationRecords.vue

@@ -1,393 +1,410 @@
 <template>
-    <el-dialog width="50%" @open="opened()" @closed="closed()" :show-close="false" class="my-info-dialog">
-        <template #title>
-            <div class="showTitles">
-                <div class="titles">校验记录详情</div>
-            </div>
-        </template>
-        <div class="bodys">
-            <!-- <el-cascader ref="cascaderHandle" :options="options" :props="{ checkStrictly: true }" clearable @change="handleChange">
-            </el-cascader> -->
-            <div class="left">
-                <el-scrollbar>
-                    <el-input placeholder="输入关键字进行过滤" v-model="filterText">
-                    </el-input>
-                    <el-tree class="filter-tree" :data="showData" :props="defaultProps" :filter-node-method="filterNode"
-                        node-key="id" :default-expanded-keys="[0]" ref="tree" @node-click="handleChange">
-                    </el-tree>
-                </el-scrollbar>
-            </div>
-            <div class="rights">
-                <div class="dateBar">
-                    <el-date-picker class="pickers" @change="changes" v-model="timeValue" type="datetimerange"
-                        range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
-                    </el-date-picker>
-                    <div class="buttons" @click="getControlRecord()">查询</div>
-                </div>
-                <el-scrollbar style="height:86%;">
-                    <div class="tables">
-                        <el-table :data="recordData" class="table" style=" width:100%" height="49vh" :header-cell-style="{
-                            background: 'rgb(30,30,30)',
-                            color: 'rgb(220,220,220)',
-                            padding: '4px',
-                            fontSize: '14px',
-                            'border-bottom': 'solid 1px rgba(77, 77, 77, 1)',
-                          }" :cell-style="{
-                            height: '40px',
-                            background: 'rgb(30,30,30)',
-                            color: 'rgb(220,220,220)',
-                            padding: '3px',
-                            fontSize: '12px',
-                            'border-bottom': '1px solid #000000'
-                          }">
-                            <el-table-column prop="time" label="日期" width="120" align="center">
-                            </el-table-column>
-                            <el-table-column prop="windturbineId" label="风机号" width="120" align="center">
-                            </el-table-column>
-                            <el-table-column prop="controls" label="控制命令" width="120" align="center">
-                            </el-table-column>
-                            <el-table-column prop="result" label="操作结果" align="center">
-                            </el-table-column>
-                            <el-table-column prop="userName" label="操作人" width="120" align="center">
-                            </el-table-column>
-                        </el-table>
-                    </div>
-                </el-scrollbar>
-                <div class="paginations">
-                    <el-pagination :hide-on-single-page="true" :page-size="currentPage" background
-                        layout="prev, pager, next" :total="total" @current-change="handleCurrentChange">
-                    </el-pagination>
-                </div>
-            </div>
+  <el-dialog
+    width="50%"
+    @open="opened()"
+    @closed="closed()"
+    :show-close="false"
+    class="my-info-dialog"
+  >
+    <template #title>
+      <div class="showTitles">
+        <div class="titles">校验记录详情</div>
+      </div>
+    </template>
+    <div class="bodyDetial">
+      <!-- <div style="width: 50%;height:200px;background-color:red;"></div>
+      <div style="width: 50%;height:200px;background-color:yellow;"></div> -->
+      <div class="left-item">
+        <el-scrollbar>
+          <el-input placeholder="输入关键字进行过滤" v-model="filterText">
+          </el-input>
+          <el-tree
+            class="filter-tree"
+            :data="showData"
+            :props="defaultProps"
+            :filter-node-method="filterNode"
+            node-key="id"
+            :default-expanded-keys="[0]"
+            ref="tree"
+            @node-click="handleChange"
+          >
+          </el-tree>
+        </el-scrollbar>
+      </div>
+      <div class="right-item">
+        <div class="dateBar">
+          <el-date-picker
+            class="pickers"
+            @change="changes"
+            v-model="timeValue"
+            type="datetimerange"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+          >
+          </el-date-picker>
+          <div class="buttons" @click="getControlRecord()">查询</div>
         </div>
-
-    </el-dialog>
+        <el-scrollbar style="height: 86%">
+          <div class="tables">
+            <el-table
+              :data="recordData"
+              class="table"
+              style="width: 100%"
+              height="49vh"
+              :header-cell-style="{
+                background: 'rgb(30,30,30)',
+                color: 'rgb(220,220,220)',
+                padding: '4px',
+                fontSize: '14px',
+                'border-bottom': 'solid 1px rgba(77, 77, 77, 1)',
+              }"
+              :cell-style="{
+                height: '40px',
+                background: 'rgb(30,30,30)',
+                color: 'rgb(220,220,220)',
+                padding: '3px',
+                fontSize: '12px',
+                'border-bottom': '1px solid #000000',
+              }"
+            >
+              <el-table-column
+                prop="time"
+                label="日期"
+                width="120"
+                align="center"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="showName"
+                label="风机号"
+                width="120"
+                align="center"
+              >
+              </el-table-column>
+              <el-table-column
+                prop="controls"
+                label="控制命令"
+                width="100"
+                align="center"
+              >
+              </el-table-column>
+              <el-table-column prop="result" label="操作结果" align="center">
+              </el-table-column>
+              <el-table-column
+                prop="userName"
+                label="操作人"
+                width="160"
+                align="center"
+              >
+              </el-table-column>
+            </el-table>
+          </div>
+        </el-scrollbar>
+        <div class="paginations">
+          <el-pagination
+            :hide-on-single-page="true"
+            :page-size="currentPage"
+            background
+            layout="prev, pager, next"
+            :total="total"
+            @current-change="handleCurrentChange"
+          >
+          </el-pagination>
+        </div>
+      </div>
+    </div>
+  </el-dialog>
 </template>
 <script>
-    import dayjs from 'dayjs'
-    import api from "api/index";
-    export default {
-        props: {
-
+import dayjs from "dayjs";
+import api from "api/index";
+export default {
+  props: {},
+  updated() {
+    if (this.timeValue.length === 0) {
+      let date = new Date();
+      this.timeValue[0] = date.getTime() - 28800000;
+      this.timeValue[1] = date.getTime() + 3600000;
+    }
+  },
+  mounted() {},
+  data() {
+    return {
+      currentPage: 10,
+      filterText: "",
+      pageIndex: 1,
+      station: [],
+      datas: {},
+      chooseStation: {},
+      timeValue: [],
+      showData: [
+        {
+          id: 0,
+          windturbineId: "全部",
+          stationId: "",
+          children: [],
         },
-        updated() {
-            if (this.timeValue.length === 0) {
-                let date = new Date()
-                this.timeValue[0] = date.getTime() - 28800000
-                this.timeValue[1] = date.getTime() + 3600000
-            }
+      ],
+      defaultProps: {
+        children: "children",
+        label: "windturbineId",
+      },
+      recordData: [],
+      total: "",
+      controlErorCodes: [
+        "控制成功",
+        "控制命令发送失败",
+        "无效的控制地址",
+        "被控设备异常",
+        "无效的控制功能",
+        "网络连接错误,检查场站通信",
+        "控制结果读取超时",
+        "未知错误",
+        "控制命令错误",
+        "收到无法识别数据",
+        "未读取到数据包",
+        "未知错误",
+        "风机操作过频繁",
+        "风机被挂牌",
+        "风机操作与风机状态不符",
+        "需要登录",
+      ],
+    };
+  },
+  methods: {
+    // getWindturbineFdc() {
+    //   api.getWindturbineFdc().then((res) => {
+    //     this.station = res.data;
+    //     this.getControlRecord();
+    //   });
+    // },
+    dataDeal() {
+      let stationList = this.$store.state.stationList;
+      this.showData[0].children = [];
+      stationList.forEach((item, index) => {
+        let obj = {};
+        obj.id = index + 1;
+        obj.windturbineId = item.name;
+        obj.stationId = item.code;
+        obj.children = [];
+        this.showData[0].children.push(obj);
+      });
+      this.datas = this.$store.state.windturbinelist
+        ? this.$store.state.windturbinelist
+        : {};
+      let arr = Object.keys(this.datas).sort();
+      for (let id of arr) {
+        let item = this.datas[id];
+        this.showData[0].children
+          .filter((val) => val.stationId === item.stationId)[0]
+          .children.push(item);
+      }
+    },
+    handleChange(value) {
+      this.chooseStation = value;
+      this.pageIndex = 1;
+      this.getControlRecord(value);
+    },
+    closed() {
+      this.pageIndex = 1;
+      this.chooseStation = {};
+      this.showData = [
+        {
+          id: 0,
+          windturbineId: "全部",
+          stationId: "",
+          children: [],
         },
-        mounted() {
+      ];
+      let stationList = this.$store.state.stationList;
+      stationList.forEach((item, index) => {
+        let obj = {};
+        obj.id = index + 1;
+        obj.windturbineId = item.name;
+        obj.stationId = item.code;
+        obj.children = [];
+        this.showData[0].children.push(obj);
+      });
 
-        },
-        data() {
-            return {
-                currentPage: 10,
-                filterText: '',
-                pageIndex: 1,
-                datas: {},
-                chooseStation: {},
-                timeValue: [],
-                showData: [
-                    {
-                        id: 0,
-                        windturbineId: '全部',
-                        stationId: "",
-                        children: [
-                            {
-                                id: 1,
-                                windturbineId: '麻黄山',
-                                stationId: "MHS_FDC",
-                                children: []
-                            }, {
-                                id: 2,
-                                windturbineId: '牛首山',
-                                stationId: "NSS_FDC",
-                                children: []
-                            }, {
-                                id: 3,
-                                windturbineId: '青山',
-                                stationId: "QS_FDC",
-                                children: []
-                            }, {
-                                id: 4,
-                                windturbineId: '石板泉',
-                                stationId: "SBQ_FDC",
-                                children: []
-                            }, {
-                                id: 5,
-                                windturbineId: '香山',
-                                stationId: "XS_FDC",
-                                children: []
-                            },
-                        ]
-                    },
-                ],
-                defaultProps: {
-                    children: 'children',
-                    label: 'windturbineId'
-                },
-                recordData: [],
-                total: '',
-                controlErorCodes: [
-                    "控制成功",
-                    "控制命令发送失败",
-                    "无效的控制地址",
-                    "被控设备异常",
-                    "无效的控制功能",
-                    "网络连接错误,检查场站通信",
-                    "控制结果读取超时",
-                    "未知错误",
-                    "控制命令错误",
-                    "收到无法识别数据",
-                    "未读取到数据包",
-                    "未知错误",
-                    "风机操作过频繁",
-                    "风机被挂牌",
-                    "风机操作与风机状态不符",
-                    "需要登录",
-                ],
+      this.$emit("closed");
+    },
+    filterNode(value, data) {
+      if (!value) return true;
+      return data.windturbineId.indexOf(value) !== -1;
+    },
+    handleCurrentChange(val) {
+      this.pageIndex = val;
+      this.getControlRecord();
+    },
+    opened() {
+      let date = new Date();
+      this.timeValue[0] = date.getTime() - 28800000;
+      this.timeValue[1] = date.getTime() + 3600000;
+      this.getControlRecord();
+    },
+    getControlRecord() {
+      api
+        .controlRecord({
+          stationId: this.chooseStation.stationId
+            ? this.chooseStation.stationId
+            : "",
+          userName: "",
+          windturbineId: this.chooseStation.id
+            ? ""
+            : this.chooseStation.stationId
+            ? this.chooseStation.windturbineId
+            : "",
+          startTime: dayjs(this.timeValue[0]).format("YYYY/MM/DD HH:mm:ss"),
+          endTime: dayjs(this.timeValue[1]).format("YYYY/MM/DD HH:mm:ss"),
+          pageSize: this.currentPage,
+          pageIndex: this.pageIndex,
+        })
+        .then((res) => {
+          if (res) {
+            let types = {
+              Start: "启动",
+              Stop: "停止",
+              Reset: "复位",
+              Maintain: "维护",
+              UnMaintain: "取消维护",
+              Lock: "挂牌",
+              UnLock: "取消挂牌",
             };
-        },
-        methods: {
-            dataDeal() {
-                this.datas = this.$store.state.windturbinelist ? this.$store.state.windturbinelist : {}
-                let arr = Object.keys(this.datas).sort()
-                for (let id of arr) {
-                    let item = this.datas[id];
-                    switch (item.windturbineId.slice(0, 2)) {
-                        case 'MG':
-                            this.showData[0].children[0].children.push(item)
-                            break;
-                        case 'NG':
-                            this.showData[0].children[1].children.push(item)
-                            break;
-                        case 'QG':
-                            this.showData[0].children[2].children.push(item)
-                            break;
-                        case 'SG':
-                            this.showData[0].children[3].children.push(item)
-                            break;
-                        case 'XG':
-                            this.showData[0].children[4].children.push(item)
-                            break;
-                    }
-                }
-                console.log(this.showData);
-            },
-            handleChange(value) {
-                this.chooseStation = value
-                this.pageIndex = 1
-                this.getControlRecord(value)
-            },
-            closed() {
-                this.pageIndex = 1
-                this.chooseStation = {}
-                this.showData = [
-                    {
-                        id: 0,
-                        windturbineId: '全部',
-                        stationId: "",
-                        children: [
-                            {
-                                id: 1,
-                                windturbineId: '麻黄山',
-                                stationId: "MHS_FDC",
-                                children: []
-                            }, {
-                                id: 2,
-                                windturbineId: '牛首山',
-                                stationId: "NSS_FDC",
-                                children: []
-                            }, {
-                                id: 3,
-                                windturbineId: '青山',
-                                stationId: "QS_FDC",
-                                children: []
-                            }, {
-                                id: 4,
-                                windturbineId: '石板泉',
-                                stationId: "SBQ_FDC",
-                                children: []
-                            }, {
-                                id: 5,
-                                windturbineId: '香山',
-                                stationId: "XS_FDC",
-                                children: []
-                            },
-                        ]
-                    },
-                ],
-                this.$emit('closed');
-            },
-            filterNode(value, data) {
-                if (!value) return true;
-                return data.windturbineId.indexOf(value) !== -1;
-            },
-            handleCurrentChange(val) {
-                this.pageIndex = val
-                this.getControlRecord()
-            },
-            opened(){
-                let date = new Date()
-                this.timeValue[0] = date.getTime() - 28800000
-                this.timeValue[1] = date.getTime() + 3600000
-                this.getControlRecord()
-            },
-            getControlRecord() {
-                api.controlRecord({
-                    stationId: this.chooseStation.stationId ? this.chooseStation.stationId : "",
-                    userName: "",
-                    windturbineId: this.chooseStation.id ? "" : this.chooseStation.stationId ? this.chooseStation.windturbineId : "",
-                    startTime: dayjs(this.timeValue[0]).format('YYYY/MM/DD HH:mm:ss'),
-                    endTime: dayjs(this.timeValue[1]).format('YYYY/MM/DD HH:mm:ss'),
-                    pageSize: this.currentPage,
-                    pageIndex: this.pageIndex,
-                }).then(res => {
-                    if (res) {
-                        let types = {
-                            Start: '启动',
-                            Stop: '停止',
-                            Reset: '复位',
-                            Maintain: '维护',
-                            UnMaintain: '取消维护',
-                            Lock: '挂牌',
-                            UnLock: '取消挂牌',
-
-                        }
-                        res.data.dataList.forEach(item => {
-                            item.time = dayjs(item.time).format('MM-DD HH:mm:ss')
-                            item.result = this.controlErorCodes[item.errorCode]
-                            item.controls = types[item.controlType]
-                        })
-                        this.total = res.data.total
-                        this.recordData = res.data.dataList
-                    }
-                })
-            },
-        },
-        watch: {
-            filterText(val) {
-                this.$refs.tree.filter(val);
-            }
-        },
-    }
+            res.data.dataList.forEach((item) => {
+              item.time = dayjs(item.time).format("MM-DD HH:mm:ss");
+              item.result = this.controlErorCodes[item.errorCode];
+              item.controls = types[item.controlType];
+              item.showName = item.windturbineId;
+            });
+            this.total = res.data.total;
+            this.recordData = res.data.dataList;
+          }
+        });
+    },
+  },
+  watch: {
+    filterText(val) {
+      this.$refs.tree.filter(val);
+    },
+  },
+};
 </script>
 
 <style scoped>
-    .showTitles {
-        display: flex;
-        flex-direction: row;
-        align-items: center;
-        justify-content: space-between;
-        margin-top: -10px;
-        font-size: 18px;
-        color: #FFFFFF;
-        height: 40px;
-    }
+.showTitles {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  margin-top: -10px;
+  font-size: 18px;
+  color: #ffffff;
+  height: 40px;
+}
 
-    .titles {
-        font-size: 16px;
-        color: #FFFFFF;
-    }
+.titles {
+  font-size: 16px;
+  color: #ffffff;
+}
 
-    .el-dialog__body {
-        padding: 30px 10px 10px 10px;
-    }
+.el-dialog__body {
+  padding: 30px 10px 10px 10px;
+}
 
-    .bodys {
-        display: flex;
-        flex-direction: row;
-        background-color: black;
-        width: 100%;
-        margin-top: -30px;
-        height: 60vh;
-    }
+.bodyDetial {
+  display: flex;
+  flex-direction: row;
+  background-color: black;
+  width: 100%;
+  margin-top: -30px;
+  height: 60vh;
+}
 
-    .left {
-        width: 20%;
-        height: 100%;
-        background-color: rgba(77, 77, 77, 1);
-        border-right: 2px solid #000000;
-    }
+.left-item {
+  width: 20%;
+  height: 100%;
+  background-color: rgba(77, 77, 77, 1);
+  border-right: 2px solid #000000;
+}
 
-    .rights {
-        width: 80%;
-        height: 100%;
-        background-color: rgba(77, 77, 77, 1);
-    }
+.right-item {
+  width: 80%;
+  height: 100%;
+  background-color: rgba(77, 77, 77, 1);
+}
 
-    .el-tree {
-        color: #FFFFFF !important;
-        background-color: rgba(77, 77, 77, 1) !important;
-    }
+.el-tree {
+  color: #ffffff !important;
+  background-color: rgba(77, 77, 77, 1) !important;
+}
 
-    .el-tree-node:focus>.el-tree-node__content {
-        background-color: #000000 !important;
-    }
+.el-tree-node:focus > .el-tree-node__content {
+  background-color: #000000 !important;
+}
 
-    .el-tree-node__content:hover {
-        background-color: #000000 !important;
-    }
+.el-tree-node__content:hover {
+  background-color: #000000 !important;
+}
 
-    .dateBar {
-        display: flex;
-        flex-direction: row;
-        align-items: center;
-        justify-content: space-between;
-        margin-left: 20px;
-    }
+.dateBar {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  margin-left: 20px;
+}
 
-    .pickers {
-        margin-left: 20px;
-    }
+.pickers {
+  margin-left: 20px;
+}
 
-    .tables {
-        margin-top: 20px;
-        width: 95%;
-        margin-left: 3%;
-    }
+.tables {
+  margin-top: 20px;
+  width: 95%;
+  margin-left: 3%;
+}
 
-    .table {
-        background-color: rgba(77, 77, 77, 1) !important;
-    }
+.table {
+  background-color: rgba(77, 77, 77, 1) !important;
+}
 
-    .el-table td,
-    .el-table th.is-leaf {
-        border-bottom: 1px solid rgba(77, 77, 77, 1) !important;
-    }
+.el-table td,
+.el-table th.is-leaf {
+  border-bottom: 1px solid rgba(77, 77, 77, 1) !important;
+}
 
-    .el-table__header {
-        width: 100% !important;
-    }
+.el-table__header {
+  width: 100% !important;
+}
 
-    .el-table__body-wrapper {
-        background-color: rgba(77, 77, 77, 1) !important;
-    }
+.el-table__body-wrapper {
+  background-color: rgba(77, 77, 77, 1) !important;
+}
 
-    .el-table::before {
-        width: 0;
-    }
+.el-table::before {
+  width: 0;
+}
 
-    tr {
-        line-height: 1.5;
-        background: #1e1e1e;
-        margin-bottom: 2px;
-        border-radius: 5px;
-    }
+tr {
+  line-height: 1.5;
+  background: #1e1e1e;
+  margin-bottom: 2px;
+  border-radius: 5px;
+}
 
-    .table-main {
-        font-size: 14px;
-        width: 600px;
-        text-align: center;
-        background: #000000;
-        margin: 5px;
-        border-collapse: separate;
-        border-spacing: 0px 5px;
-    }
+.table-main {
+  font-size: 14px;
+  width: 600px;
+  text-align: center;
+  background: #000000;
+  margin: 5px;
+  border-collapse: separate;
+  border-spacing: 0px 5px;
+}
 
-    .paginations {
-        display: flex;
-        flex-direction: row-reverse;
-    }
+.paginations {
+  display: flex;
+  flex-direction: row-reverse;
+}
 </style>

+ 206 - 184
src/components/control/areaCard.vue

@@ -1,95 +1,98 @@
 /* 自定义tabs */
 <template>
-  <div class="body" :style="style">
-    <img class="logo" src="../../assets/img/logo.png" alt="" />
-    <div class="title">
-      <div>{{ title }}</div>
-      <div style="display: flex; flex-direction: row; align-items: center">
-        <div v-for="(item, index) in controlTypeList" :key="index">
-          <div
-            v-if="!item.type"
-            :class="
-              index === 0
-                ? 'controlTypesLeft'
-                : index === 4
-                ? 'controlTypesRight'
-                : 'controlTypes'
-            "
-            @click="handleTypeChange(item)"
-          >
-            {{ item.name }}
-          </div>
-          <div
-            v-if="item.type"
-            :class="
-              index === 0
-                ? 'onControlTypesLeft'
-                : index === 4
-                ? 'onControlTypesRight'
-                : 'onControlTypes'
-            "
-            @click="handleTypeChange(item)"
-          >
-            {{ item.name }}
-          </div>
-        </div>
-      </div>
-    </div>
-    <div style="margin-top: 50px; height: 85%" @contextmenu="contextmenu">
-      <div class="scoll currentScroll">
-        <div class="currentScroll" style="height: 100%; overflow-y: scroll">
-          <div class="matrix" v-if="startList.length > 0">
-            <div class="problemTitle">启动</div>
-            <MatrixBlock
-              @on-click="handleDetial"
-              @choose-click="handleClick"
-              :dataList="startList"
-            >
-            </MatrixBlock>
-          </div>
-          <div class="matrix" v-if="stopList.length > 0">
-            <div class="problemTitle">停机</div>
-            <MatrixBlock
-              @on-click="handleDetial"
-              @choose-click="handleClick"
-              :dataList="stopList"
+  <div>
+    <div class="body" :style="style">
+      <img class="logo" src="../../assets/img/logo.png" alt="" />
+      <div class="title">
+        <div>{{ title }}</div>
+        <div style="display: flex; flex-direction: row; align-items: center">
+          <div v-for="(item, index) in controlTypeList" :key="index">
+            <div
+              v-if="!item.type"
+              :class="
+                index === 0
+                  ? 'controlTypesLeft'
+                  : index === controlTypeList.length - 1
+                  ? 'controlTypesRight'
+                  : 'controlTypes'
+              "
+              @click="handleTypeChange(item)"
             >
-            </MatrixBlock>
-          </div>
-          <div class="matrix" v-if="maintainList.length > 0">
-            <div class="problemTitle">维护</div>
-            <MatrixBlock
-              @on-click="handleDetial"
-              @choose-click="handleClick"
-              :dataList="maintainList"
+              {{ item.name }}
+            </div>
+            <div
+              v-if="item.type"
+              :class="
+                index === 0
+                  ? 'onControlTypesLeft'
+                  : index === controlTypeList.length - 1
+                  ? 'onControlTypesRight'
+                  : 'onControlTypes'
+              "
+              @click="handleTypeChange(item)"
             >
-            </MatrixBlock>
+              {{ item.name }}
+            </div>
           </div>
-          <div class="matrix" v-if="unMaintainList.length > 0">
-            <div class="problemTitle">取消维护</div>
-            <MatrixBlock
-              @on-click="handleDetial"
-              @choose-click="handleClick"
-              :dataList="unMaintainList"
-            >
-            </MatrixBlock>
+        </div>
+      </div>
+      <div style="margin-top: 50px; height: 85%" @contextmenu="contextmenu">
+        <div class="scoll">
+          <div class="currentScroll" style="height: 100%; overflow-y: scroll">
+            <div class="matrix" v-if="startList.length > 0">
+              <div class="problemTitle titleSty">启动</div>
+              <MatrixBlock
+                @on-click="handleDetial"
+                @choose-click="handleClick"
+                :dataList="startList"
+              >
+              </MatrixBlock>
+            </div>
+            <div class="matrix" v-if="stopList.length > 0">
+              <div class="problemTitle titleSty">停机</div>
+              <MatrixBlock
+                @on-click="handleDetial"
+                @choose-click="handleClick"
+                :dataList="stopList"
+              >
+              </MatrixBlock>
+            </div>
+            <div class="matrix" v-if="maintainList.length > 0">
+              <div class="problemTitle titleSty">维护</div>
+              <MatrixBlock
+                @on-click="handleDetial"
+                @choose-click="handleClick"
+                :dataList="maintainList"
+              >
+              </MatrixBlock>
+            </div>
+            <div class="matrix" v-if="unMaintainList.length > 0">
+              <div class="problemTitle titleSty">取消维护</div>
+              <MatrixBlock
+                @on-click="handleDetial"
+                @choose-click="handleClick"
+                :dataList="unMaintainList"
+              >
+              </MatrixBlock>
+            </div>
           </div>
         </div>
       </div>
+      <div v-if="current == 1" class="send" @click="handleSend">发送</div>
+      <!-- <div v-if="current == 1" class="sends">发送</div> -->
     </div>
-    <div v-if="current == 1" class="send" @click="handleSend">发送</div>
-    <!-- <div class="success" v-if="showFlag&&current===0">指令发送成功</div> -->
+
+    <WindturbineDetailPages
+      v-model="dialogVisible"
+      @close="handleClose"
+      :windturbine="currentWindturbine"
+    >
+    </WindturbineDetailPages>
   </div>
-  <WindturbineDetailPages
-    v-model="dialogVisible"
-    @close="handleClose"
-    :windturbine="currentWindturbine"
-  >
-  </WindturbineDetailPages>
   <StationSvgDetailPages
     v-model="svgVisible"
     :stationName="stationName"
-    :svgWeb="svgWeb"
+    :currentStation="svgWeb"
     @close="handleClose"
   >
   </StationSvgDetailPages>
@@ -101,6 +104,7 @@ import WindturbineDetailPages from "../WindturbineDetailPages.vue";
 import MatrixBlock from "../matrixBlock.vue";
 import MessageBridge from "utils/MessageBridge";
 import api from "api/index";
+import { debounce } from "lodash";
 import StationSvgDetailPages from "../stationSvgDetailPages.vue";
 export default {
   name: "gy-card",
@@ -113,6 +117,10 @@ export default {
     this.initData();
     this.suggestion();
     this.getControlType();
+    this.handleWindturbineChange();
+    this.intervals = setInterval(this.handleWindturbineChange, 3000);
+    this.suggestion();
+    this.sugIntervals = setInterval(this.suggestion, 15000);
   },
   emits: ["parentRun"],
   props: {
@@ -128,8 +136,10 @@ export default {
   },
   data() {
     return {
+      intervals: null,
+      sugIntervals: null,
+      windturbineList: {},
       current: 1,
-      windturbinelist: {},
       titleList: [],
       startList: [],
       stopList: [],
@@ -139,12 +149,11 @@ export default {
       sendList: [],
       currentWindturbine: {},
       dialogVisible: false,
-      svgVisible: false,
-      // showFlag: false,
+      // svgVisible: false,
       svgWeb: "",
-      stationName: "",
+      // stationName: "",
       // 定时器
-      timer: "",
+      // timer: "",
       controlTypeList: [],
       controlErorCodes: [
         "控制成功",
@@ -164,6 +173,7 @@ export default {
         "风机操作与风机状态不符",
         "需要登录",
       ],
+      indexsss: 0,
     };
   },
   computed: {
@@ -185,61 +195,57 @@ export default {
     },
     initData: function () {
       let mb = MessageBridge.getInstance();
-      mb.unregister({ key: "/topic/suggestion" });
-      let vs = [{ key: "/topic/suggestion", action: this.suggestion }];
       let vss = [
         { key: "/topic/voice-control", action: this.windturbineMessage },
       ];
-      this.vss = vss;
-      mb.register(vs);
       mb.register(vss);
     },
-    suggestion(msg, headers) {
-      msg ? this.$store.commit("suggestion", JSON.parse(msg)) : "";
-      let bd = BackgroundData.getInstance();
-      this.titleList = msg ? JSON.parse(msg) : this.$store.state.suggestion;
-      if (this.current === 0) {
-        let dateList = [];
-        this.titleList.forEach((item) => {
-          let status = this.controlTypeList.filter(
-            (val) =>
-              val.stationId ===
-              this.windturbinelist[item.windturbineId].stationId
-          )[0].type;
-          if (status) {
-            let arr = Object.keys(this.windturbinelist).sort();
-            this.windturbinelist =
-              arr.length !== 0
-                ? this.windturbinelist
-                : this.$store.state.windturbinelist;
-            switch (item.operateStyle) {
-              case "Start":
-                this.windturbinelist[item.windturbineId].controlType = 1;
-                break;
-              case "Stop":
-                this.windturbinelist[item.windturbineId].controlType = 2;
-                break;
-              case "Maintain":
-                this.windturbinelist[item.windturbineId].controlType = 6;
-                break;
-              case "UnMaintain":
-                this.windturbinelist[item.windturbineId].controlType = 8;
-                break;
-            }
-            dateList.push(this.windturbinelist[item.windturbineId]);
-          }
-        });
-        let mss = {};
-        mss.type = "send";
-        mss.deviceType = "Auto";
-        this.timer = setTimeout(() => {
-          if (dateList.length > 0) {
-            this.sendCommand(mss, dateList);
+    suggestion() {
+      api.recommendation().then((res) => {
+        if (res.data) {
+          this.titleList = res.data;
+          if (this.current === 0) {
+            let dateList = [];
+            this.titleList.forEach((item) => {
+              let status = this.controlTypeList.filter(
+                (val) =>
+                  val.stationId ===
+                  this.windturbinelist[item.windturbineId].stationId
+              )[0].type;
+              if (status) {
+                let arr = Object.keys(this.windturbinelist).sort();
+                this.windturbinelist =
+                  arr.length !== 0
+                    ? this.windturbinelist
+                    : this.$store.state.windturbinelist;
+                switch (item.operateStyle) {
+                  case "Start":
+                    this.windturbinelist[item.windturbineId].controlType = 1;
+                    break;
+                  case "Stop":
+                    this.windturbinelist[item.windturbineId].controlType = 2;
+                    break;
+                  case "Maintain":
+                    this.windturbinelist[item.windturbineId].controlType = 6;
+                    break;
+                  case "UnMaintain":
+                    this.windturbinelist[item.windturbineId].controlType = 8;
+                    break;
+                }
+                dateList.push(this.windturbinelist[item.windturbineId]);
+              }
+            });
+            let mss = {};
+            mss.type = "send";
+            mss.deviceType = "Auto";
+            setTimeout(() => {
+              if (dateList.length > 0) {
+                this.sendCommand(mss, dateList);
+              }
+            }, 3000);
           }
-          // this.showFlag = true
-          clearInterval(this.timer);
-        }, 3000);
-      }
+        }
+      });
     },
     windturbineMessage(msg) {
       if (this.$store.state.current === 1 || this.$store.state.current === 0) {
@@ -260,12 +266,7 @@ export default {
         } else if (arr[0] === "CLOSE") {
           this.dialogVisible = false;
           this.svgVisible = false;
-        } else if (arr[0] === "OPEN_SYZ") {
-          this.showSvg = true;
-          this.svgVisible = true;
-          this.svgWeb = arr[1];
-          this.stationName = this.boosterStation[arr[1]].name;
-        } else if (
+        }  else if (
           arr[0] === "CONTROL_START" ||
           arr[0] === "CONTROL_STOP" ||
           arr[0] === "CONTROL_MAINTAIN" ||
@@ -412,7 +413,7 @@ export default {
     },
     handleClose() {
       this.dialogVisible = false;
-      this.svgVisible = false;
+      // this.svgVisible = false;
     },
     handleSend() {
       if (this.chooseList.length > 0) {
@@ -525,7 +526,6 @@ export default {
         });
         api.windturbControl(pairs).then((res) => {
           if (res) {
-            // this.showFlag = false
             this.controlSuccess(res);
           }
         });
@@ -613,16 +613,14 @@ export default {
         for (let v in msg.data) {
           let val = msg.data[v];
           if (val.errorCode > 0) {
-            iserror = true;
-            mss += `${val.windturbineId}  ${
-              this.controlErorCodes[val.errorCode]
-            }\n`;
+                    iserror = true;
+                    mss += `${val.windturbineId}  ${this.controlErorCodes[val.errorCode]
+                        }\n`;
+          } else {
+              mss += `${val.windturbineId}\n`;
           }
         }
         let tp = iserror ? "warning" : "success";
-        if (!iserror) {
-          mss = "控制成功";
-        }
         this.$notify({
           title: "控制",
           message: mss,
@@ -654,14 +652,7 @@ export default {
         duration: 3000,
       });
     },
-    sendMessage(url1) {
-      this.messageUrl = url1;
-      // let link = document.createElement('a')
-      // link.href = url1
-      // link.click()
-    },
     handleTypeChange(val) {
-      //   val.type = !val.type;
       let bd = BackgroundData.getInstance();
       if (!bd.LoginUser) {
         this.$notify({
@@ -686,17 +677,16 @@ export default {
           }
         });
     },
-  },
-  watch: {
-    "$store.getters.windturbinelist": {
-      deep: true,
-      handler: function (json) {
+    handleWindturbineChange() {
+      api.getWindturbine().then((res) => {
+        let json = res.data;
+        this.$store.commit("windturbinelist", json);
         this.windturbinelist = json;
         let arr = Object.keys(json).sort();
-        this.stopList = [];
-        this.startList = [];
-        this.maintainList = [];
-        this.unMaintainList = [];
+        let stopList = [];
+        let startList = [];
+        let maintainList = [];
+        let unMaintainList = [];
         for (let id of arr) {
           let val = json[id];
           this.chooseList.forEach((item) => {
@@ -708,19 +698,19 @@ export default {
             if (item.windturbineId === val.windturbineId) {
               val.operateStyle = item.operateStyle;
               if (item.operateStyle === "Start" && val.status === 2) {
-                this.startList.push(val);
+                startList.push(val);
               } else if (item.operateStyle === "Stop" && val.status === 4) {
                 if (item.reasonType === "ElectricityRestrictions") {
                   val.reasonType = item.reasonType;
                 }
-                this.stopList.push(val);
+                stopList.push(val);
               } else if (item.operateStyle === "Maintain" && val.status === 2) {
-                this.maintainList.push(val);
+                maintainList.push(val);
               } else if (
                 item.operateStyle === "UnMaintain" &&
                 val.status === 6
               ) {
-                this.unMaintainList.push(val);
+                unMaintainList.push(val);
               }
             }
           });
@@ -735,37 +725,49 @@ export default {
           let stopFlag = false;
           let maintainFlag = false;
           let unMaintainFlag = false;
-          this.startList.forEach((param, index) => {
+          startList.forEach((param, index) => {
             if (item.windturbineId === param.windturbineId) {
               starIndex = index;
               starFlag = true;
             }
           });
-          this.stopList.forEach((param, index) => {
+          stopList.forEach((param, index) => {
             if (item.windturbineId === param.windturbineId) {
               stopIndex = index;
               stopFlag = true;
             }
           });
-          this.maintainList.forEach((param, index) => {
+          maintainList.forEach((param, index) => {
             if (item.windturbineId === param.windturbineId) {
               maintainIndex = index;
               maintainFlag = true;
             }
           });
-          this.unMaintainList.forEach((param, index) => {
+          unMaintainList.forEach((param, index) => {
             if (item.windturbineId === param.windturbineId) {
               unMaintainIndex = index;
               unMaintainFlag = true;
             }
           });
-          starFlag ? this.startList.splice(starIndex, 1) : "";
-          stopFlag ? this.stopList.splice(stopIndex, 1) : "";
-          maintainFlag ? this.maintainList.splice(maintainIndex, 1) : "";
-          unMaintainFlag ? this.unMaintainList.splice(unMaintainIndex, 1) : "";
+          starFlag ? startList.splice(starIndex, 1) : "";
+          stopFlag ? stopList.splice(stopIndex, 1) : "";
+          maintainFlag ? maintainList.splice(maintainIndex, 1) : "";
+          unMaintainFlag ? unMaintainList.splice(unMaintainIndex, 1) : "";
         });
-      },
+        this.stopList = stopList;
+        this.startList = startList;
+        this.maintainList = maintainList;
+        this.unMaintainList = unMaintainList;
+      });
     },
+  },
+  unmounted() {
+    clearInterval(this.intervals);
+    clearInterval(this.sugIntervals);
+    this.sugIntervals = null;
+    this.intervals = null;
+  },
+  watch: {
     "$store.getters.current": {
       handler: function (json) {
         this.current = json;
@@ -804,12 +806,10 @@ export default {
           let mss = {};
           mss.type = "send";
           mss.deviceType = "Auto";
-          this.timer = setTimeout(() => {
+          setTimeout(() => {
             if (dateList.length > 0) {
               this.sendCommand(mss, dateList);
             }
-            this.showFlag = false;
-            clearInterval(this.timer);
           }, 3000);
         }
       },
@@ -828,7 +828,6 @@ export default {
 
 .body .scoll {
   height: 91%;
-  overflow-y: scroll;
 }
 
 .title {
@@ -874,7 +873,7 @@ export default {
 }
 
 .problemTitle {
-  font-size: 12px;
+  /* font-size: 12px; */
   color: #bfbfbf;
   margin-top: 20px;
   margin-bottom: 20px;
@@ -894,7 +893,19 @@ export default {
   bottom: 20px;
   right: 10px;
 }
-
+.sends {
+  width: 86px;
+  height: 26px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: #999999;
+  color: #ffffff;
+  font-size: 14px;
+  position: absolute;
+  bottom: 20px;
+  right: 10px;
+}
 .success {
   display: flex;
   align-items: center;
@@ -969,4 +980,15 @@ export default {
   border-bottom-right-radius: 15px;
   background-color: rgba(37, 116, 219, 1);
 }
-</style>
+</style>
+
+<style lang="less">
+.currentScroll{
+    .matrix{
+        .titleSty {
+            font-size: 14px;
+            font-weight: bold;
+        }
+    }
+}
+</style>

+ 445 - 259
src/components/control/controlAllArea.vue

@@ -3,7 +3,7 @@
     <div class="body">
       <img class="logo" src="../../assets/img/logo.png" alt="" />
       <div class="titleBar">
-        <div class="title">设备区</div>
+        <div class="title" @click="parametersContrast()">设备区</div>
         <el-select
           @change="listedChange()"
           class="inputs"
@@ -19,52 +19,77 @@
           </el-option>
         </el-select>
       </div>
-      <div style="margin-top: 20px; margin-left: 35px; height: 85%">
-        <div class="scoll">
-          <div
-            class="matrix currentScroll"
-            style="height: 100%;overflow-y:scroll"
-            v-if="showList.length > 0"
-          >
-            <!-- <div class="problemTitle">待启动</div> -->
+      <div
+        class="content"
+        style="
+          margin-top: 20px;
+          margin-left: 35px;
+          height: 85%;
+          overflow-y: auto;
+        "
+      >
+        <!-- <el-scrollbar>
+          <div class="scoll"> -->
+        <div class="matrix" v-if="showList.length > 0">
+          <box-select node=".box" @selectList="selectList">
+            
+                <!-- v-if="showWh(showList[0])" -->
             <MatrixBlock
-              @choose-click="handleClick"
-              @on-click="handleDetails"
-              :dataList="showList"
+                v-if="showWh(showList[0])"
+                @choose-click="handleClick"
+                @on-click="handleDetails"
+                :dataList="showList"
             >
             </MatrixBlock>
-          </div>
+            <MatrixBlockPv
+                v-else
+              @on-click="handleDetialPv"
+              :dataList="showList"
+            >
+            </MatrixBlockPv>
+          </box-select>
         </div>
+        <!-- </div>
+        </el-scrollbar> -->
       </div>
     </div>
+
     <WindturbineDetailPages
       v-model="dialogVisible"
+      :showSvg="showSvg"
       @close="handleClose"
-      :svgWeb="svgWeb"
       :windturbine="currentWindturbine"
     ></WindturbineDetailPages>
-    <StationSvgDetailPages
-    v-model="showSvg"
-    :stationName="stationName"
-    :svgWeb="svgWeb"
-    @close="close"
-  ></StationSvgDetailPages>
+    <PvDetailPages v-model="dialogPvDia" @close="handleClose" :windturbine="currentWindturbinePv">
+    </PvDetailPages>
+    <ParametersContrast
+      :chooseList="chooseList"
+      v-model="parametersDisplay"
+    ></ParametersContrast>
   </div>
 </template>
 
 <script>
 import WindturbineDetailPages from "../WindturbineDetailPages.vue";
+import PvDetailPages from "components/PvDetailPages.vue";
 import MatrixBlock from "../matrixBlock.vue";
-import StationSvgDetailPages from "../stationSvgDetailPages.vue";
+import MatrixBlockPv from "../matrixBlockPv.vue";
+import EaxyMatrxBlock from "../eaxyMatrixBlock.vue";
 import BackgroundData from "utils/BackgroundData";
-import MessageBridge from "utils/MessageBridge";
 import api from "api/index";
+import boxSelect from "components/boxSelect.vue";
+import ParametersContrast from "./parametersContrast.vue";
+import MessageBridge from "utils/MessageBridge";
 export default {
   name: "ProblemArea",
   components: {
     WindturbineDetailPages,
+    PvDetailPages,
     MatrixBlock,
-    StationSvgDetailPages,
+    MatrixBlockPv,
+    boxSelect,
+    ParametersContrast,
+    EaxyMatrxBlock,
   },
   props: {
     current: {
@@ -76,14 +101,18 @@ export default {
   },
   data() {
     return {
+      allNames: [],
+      allList: {},
       dataList: [],
       showList: [],
       chooseList: [],
       lockValues: [],
       currentWindturbine: {},
+      currentWindturbinePv: {},
       dialogVisible: false,
+      dialogPvDia: false,
       showSvg: false,
-      svgWeb: "",
+      parametersDisplay: false,
       windturbinelist: {},
       options: [
         {
@@ -106,28 +135,9 @@ export default {
           value: "4",
           label: "挂牌",
         },
-        {
-          value: "5",
-          label: "麻黄山",
-        },
-        {
-          value: "6",
-          label: "牛首山",
-        },
-        {
-          value: "7",
-          label: "青山",
-        },
-        {
-          value: "8",
-          label: "石板泉",
-        },
-        {
-          value: "9",
-          label: "香山",
-        },
       ],
       selectValue: "0",
+      intervals: null,
       controlErorCodes: [
         "控制成功",
         "控制命令发送失败",
@@ -151,83 +161,145 @@ export default {
   computed: {},
   created: function () {
     this.initData();
+    this.handleWindturbineChange();
     this.controls();
     this.getLocks();
+    this.intervals = setInterval(() =>{
+        this.handleWindturbineChange
+    }, 3000);
   },
   methods: {
+    showWh(item) {
+        let show = false
+        if (item.stationId) {
+            show = true
+        }
+        return show
+    },
+    selectList(val) {
+      val.forEach((item) => {
+        this.handleClick(this.windturbinelist[item.id]);
+      });
+    },
     controls() {
-      let json = this.$store.state.windturbinelist;
-      this.dataList = [];
-      this.showList = [];
-      let arr = Object.keys(json).sort();
-      for (let id of arr) {
-        let val = json[id];
-        this.chooseList.forEach((item) => {
-          if (item.windturbineId === val.windturbineId) {
-            val.active = true;
-          }
+        this.options = [
+            {
+            value: "0",
+            label: "问题设备",
+            },
+            {
+            value: "1",
+            label: "故障",
+            },
+            {
+            value: "2",
+            label: "维护",
+            },
+            {
+            value: "3",
+            label: "离线",
+            },
+            {
+            value: "4",
+            label: "挂牌",
+            },
+        ];
+        let stationList = this.$store.state.stationList;
+        stationList.forEach((item, index) => {
+            if (item.id.indexOf("FDC") != -1 || item.id.indexOf("GDC") != -1) {
+                let obj = {};
+                obj.value = String(index + 6);
+                obj.label = item.name;
+                obj.stationId = item.code || item.id;
+                this.options.push(obj);
+            }
         });
-        this.dataList.push(val);
-        switch (Number(this.selectValue)) {
-          case 0:
-            if (
-              val.status === 5 ||
-              val.status === 6 ||
-              val.status === 7 ||
-              val.lockValue > 0
-            ) {
-              this.showList.push(val);
+        // let json = this.$store.state.windturbinelist;
+        let wswind = JSON.parse(window.sessionStorage.getItem('windSbq'))
+        let pv = JSON.parse(window.sessionStorage.getItem('pvSbq'))
+        let json = {}
+        if (wswind && pv) {
+            json = {...wswind, ...pv}
+            this.dataList = [];
+            const showList = [];
+            let arr = Object.keys(json).sort();
+            for (let id of arr) {
+                let val = json[id];
+                this.chooseList.forEach((item) => {
+                if (item.windturbineId === val.windturbineId) {
+                    val.active = true;
+                }
+                });
+                this.dataList.push(val);
+                switch (Number(this.selectValue)) {
+                case 0:
+                    if (
+                    val.status === 5 ||
+                    val.status === 6 ||
+                    val.status === 7 ||
+                    val.lockValue > 0
+                    ) {
+                    showList.push(val);
+                    }
+                    break;
+                case 1:
+                    val.status === 5 ? showList.push(val) : "";
+                    break;
+                case 2:
+                    val.status === 6 ? showList.push(val) : "";
+                    break;
+                case 3:
+                    val.status === 7 ? showList.push(val) : "";
+                    break;
+                case 4:
+                    val.lockValue > 0 ? showList.push(val) : "";
+                    break;
+                default:
+                    if (
+                    val.stationId ===
+                    this.options.filter((ops) => ops?.value === this.selectValue)[0]
+                        .stationId
+                    ) {
+                    showList.push(val);
+                    }
+                    break;
+                }
             }
-            break;
-          case 1:
-            val.status === 5 ? this.showList.push(val) : "";
-            break;
-          case 2:
-            val.status === 6 ? this.showList.push(val) : "";
-            break;
-          case 3:
-            val.status === 7 ? this.showList.push(val) : "";
-            break;
-          case 4:
-            val.lockValue > 0 ? this.showList.push(val) : "";
-            break;
-          case 5:
-            val.windturbineId.substring(0, 2) === "MG"
-              ? this.showList.push(val)
-              : "";
-            break;
-          case 6:
-            val.windturbineId.substring(0, 2) === "NG"
-              ? this.showList.push(val)
-              : "";
-            break;
-          case 7:
-            val.windturbineId.substring(0, 2) === "QG"
-              ? this.showList.push(val)
-              : "";
-            break;
-          case 8:
-            val.windturbineId.substring(0, 2) === "SG"
-              ? this.showList.push(val)
-              : "";
-            break;
-          case 9:
-            val.windturbineId.substring(0, 2) === "XG"
-              ? this.showList.push(val)
-              : "";
-            break;
+            let checkoutList = BackgroundData.getInstance().checkouts;
+            checkoutList.forEach((item) => {
+                let showIndex = null;
+                showList.forEach((param, index) => {
+                if (item.windturbineId === param.windturbineId) {
+                    showIndex = index;
+                }
+                });
+                showList.splice(showIndex, 1);
+            });
+            showList.sort((a,b)=>{
+              let aSubString = '0', bSubString = '0'
+              let aStation = '1', bStation = '2'
+              if(a.windturbineId && b.windturbineId){
+                aSubString = a.windturbineId.substring(a.windturbineId.lastIndexOf('_')+1)
+                bSubString = b.windturbineId.substring(b.windturbineId.lastIndexOf('_')+1)
+
+                aStation = a.windturbineId.substring(0, a.windturbineId.lastIndexOf('_'))
+                bStation = b.windturbineId.substring(0, b.windturbineId.lastIndexOf('_'))
+
+              }else if(a.id && b.id){
+                aSubString = a.id.substring(a.id.lastIndexOf('_')+1)
+                bSubString = b.id.substring(b.id.lastIndexOf('_')+1)
+
+                aStation = a.id.substring(0, a.id.lastIndexOf('_'))
+                bStation = b.id.substring(0, b.id.lastIndexOf('_'))
+              }
+              if(aStation === bStation){
+                return parseInt(aSubString) - parseInt(bSubString)
+              }else{
+                return 0
+              }
+            })
+            this.showList = showList
         }
-      }
-      let checkoutList = BackgroundData.getInstance().checkouts;
-      checkoutList.forEach((item) => {
-        let showIndex = null;
-        this.showList.forEach((param, index) => {
-          if (item.windturbineId === param.windturbineId) {
-            showIndex = index;
-          }
-        });
-        this.showList.splice(showIndex, 1);
-      });
     },
     getLocks() {
       api.getCustomerLock().then((res) => {
@@ -237,11 +309,11 @@ export default {
       });
     },
     initData: function () {
-      let mb = MessageBridge.getInstance();
-      let vss = [
-        { key: "/topic/voice-control", action: this.windturbineMessage },
-      ];
-      mb.register(vss);
+        let mb = MessageBridge.getInstance();
+        let vss = [
+            { key: "/topic/voice-control", action: this.windturbineMessage },
+        ];
+        mb.register(vss);
     },
     windturbineMessage(msg) {
       if (this.$store.state.current === 2) {
@@ -259,12 +331,7 @@ export default {
           this.dialogVisible = true;
         } else if (arr[0] === "CLOSE") {
           this.dialogVisible = false;
-        } else if (arr[0] === "OPEN_SYZ") {
-          this.currentWindturbine = this.windturbinelist[arr[1]];
-          this.showSvg = true;
-          this.svgVisible = true;
-          this.svgWeb = arr[1];
-        } else if (
+        }  else if (
           arr[0] === "CONTROL_START" ||
           arr[0] === "CONTROL_STOP" ||
           arr[0] === "CONTROL_MAINTAIN"
@@ -346,12 +413,6 @@ export default {
         this.selectValue === "4"
       ) {
         menuTemplate = [
-          // {
-          //     label: "标注",
-          //     click() {
-          //         that.sendLock({ type: "marking" });
-          //     },
-          // },
           {
             label: "挂牌",
             submenu: [
@@ -399,37 +460,43 @@ export default {
               that.sendLock({ value: "UnLock" });
             },
           },
+          {
+            label: "参数对比",
+            click() {
+              that.parametersContrast();
+            },
+          },
         ];
       } else {
         menuTemplate = [
           {
             label: "启动",
             click() {
-              that.sendCommand({ controlType: "1" });
+              that.sendCommand({ controlType: "1", deviceType: "Manual" });
             },
           },
           {
             label: "停机",
             click() {
-              that.sendCommand({ controlType: "2" });
+              that.sendCommand({ controlType: "2", deviceType: "Manual" });
             },
           },
           {
             label: "复位",
             click() {
-              that.sendCommand({ controlType: "5" });
+              that.sendCommand({ controlType: "5", deviceType: "Manual" });
             },
           },
           {
             label: "维护",
             click() {
-              that.sendCommand({ controlType: "6" });
+              that.sendCommand({ controlType: "6", deviceType: "Manual" });
             },
           },
           {
             label: "取消维护",
             click() {
-              that.sendCommand({ controlType: "8" });
+              that.sendCommand({ controlType: "8", deviceType: "Manual" });
             },
           },
           {
@@ -479,12 +546,12 @@ export default {
               that.sendLock({ value: "UnLock" });
             },
           },
-          // {
-          //     label: "标注",
-          //     click() {
-          //         that.sendLock({ type: "marking" });
-          //     },
-          // },
+          {
+            label: "参数对比",
+            click() {
+              that.parametersContrast();
+            },
+          },
         ];
       }
 
@@ -530,6 +597,8 @@ export default {
             lockType: item.lockType,
             userName: `system_${bd.LoginUser.name}`,
             userId: 0,
+            auto: false,
+            deviceType: msg.deviceType,
           };
           pairs[ct.windturbineId] = ct;
         });
@@ -587,10 +656,6 @@ export default {
       }
     },
 
-    /* 清除所有选择 */
-    clearSelected() {
-      this.chooseList = [];
-    },
     /* 控制成功 */
     controlSuccess(msg) {
       let bd = BackgroundData.getInstance();
@@ -612,9 +677,9 @@ export default {
         }
       }
       let tp = iserror ? "warning" : "success";
-      if (!iserror) {
-        mss = "控制成功";
-      }
+      // if (!iserror) {
+      //   mss = "控制成功";
+      // }
 
       this.$notify({
         title: "控制",
@@ -657,7 +722,21 @@ export default {
     },
     listedChange() {
       this.chooseList = [];
-      this.showList = [];
+      const showList = [];
+      if (Number(this.selectValue) >= 6) {
+        console.log(
+          this.options.filter((ops) => ops?.value === this.selectValue)[0]
+            .stationId
+        );
+        this.$store.commit(
+          "currentStation",
+          this.options.filter((ops) => ops?.value === this.selectValue)[0]
+            .stationId
+        );
+      } else {
+        this.$store.commit("currentStation", "");
+      }
+      console.log(this.$store.state.currentStation);
       this.dataList.forEach((val) => {
         val.active = false;
         switch (Number(this.selectValue)) {
@@ -668,142 +747,234 @@ export default {
               val.status === 7 ||
               val.lockValue > 0
             ) {
-              this.showList.push(val);
+              showList.push(val);
             }
             break;
           case 1:
-            val.status === 5 ? this.showList.push(val) : "";
+            val.status === 5 ? showList.push(val) : "";
             break;
           case 2:
-            val.status === 6 ? this.showList.push(val) : "";
+            val.status === 6 ? showList.push(val) : "";
             break;
           case 3:
-            val.status === 7 ? this.showList.push(val) : "";
+            val.status === 7 ? showList.push(val) : "";
             break;
           case 4:
-            val.lockValue > 0 ? this.showList.push(val) : "";
-            break;
-          case 5:
-            val.windturbineId.substring(0, 2) === "MG"
-              ? this.showList.push(val)
-              : "";
-            break;
-          case 6:
-            val.windturbineId.substring(0, 2) === "NG"
-              ? this.showList.push(val)
-              : "";
-            break;
-          case 7:
-            val.windturbineId.substring(0, 2) === "QG"
-              ? this.showList.push(val)
-              : "";
+            val.lockValue > 0 ? showList.push(val) : "";
             break;
-          case 8:
-            val.windturbineId.substring(0, 2) === "SG"
-              ? this.showList.push(val)
-              : "";
-            break;
-          case 9:
-            val.windturbineId.substring(0, 2) === "XG"
-              ? this.showList.push(val)
-              : "";
+          default:
+            if (Number(this.selectValue) < 12) {
+                if (
+                  val.stationId ===
+                  this.options.filter((ops) => ops?.value === this.selectValue)[0]
+                    .stationId
+                ) {
+                  showList.push(val);
+                }
+            } else {
+                if (
+                  val.station ===
+                  this.options.filter((ops) => ops?.value === this.selectValue)[0]
+                    .stationId
+                ) {
+                  showList.push(val);
+                }
+            }
             break;
         }
       });
+      showList.sort((a,b)=>{
+        let aSubString = '0', bSubString = '0'
+        let aStation = '1', bStation = '2'
+        if(a.windturbineId && b.windturbineId){
+          aSubString = a.windturbineId.substring(a.windturbineId.lastIndexOf('_')+1)
+          bSubString = b.windturbineId.substring(b.windturbineId.lastIndexOf('_')+1)
+
+          aStation = a.windturbineId.substring(0, a.windturbineId.lastIndexOf('_'))
+          bStation = b.windturbineId.substring(0, b.windturbineId.lastIndexOf('_'))
+
+        }else if(a.id && b.id){
+          aSubString = a.id.substring(a.id.lastIndexOf('_')+1)
+          bSubString = b.id.substring(b.id.lastIndexOf('_')+1)
+
+          aStation = a.id.substring(0, a.id.lastIndexOf('_'))
+          bStation = b.id.substring(0, b.id.lastIndexOf('_'))
+        }
+        if(aStation === bStation){
+          return parseInt(aSubString) - parseInt(bSubString)
+        }else{
+          return 0
+        }
+      })
+      this.showList = showList
     },
     handleDetails(itm) {
       this.dialogVisible = true;
       this.currentWindturbine = itm;
     },
+    handleDetialPv(item) {
+        this.dialogPvDia = true;
+        this.currentWindturbinePv = item;
+    },
     handleClose() {
       this.dialogVisible = false;
       this.showSvg = false;
       this.getLocks();
     },
-  },
-  watch: {
-    "$store.getters.windturbinelist": {
-      deep: true,
-      handler: function (json) {
-        this.windturbinelist = json;
-        this.dataList = [];
-        this.showList = [];
-        let arr = Object.keys(json).sort();
-        for (let id of arr) {
-          let val = json[id];
-          this.chooseList.forEach((item) => {
-            if (item.windturbineId === val.windturbineId) {
-              val.active = true;
+    parametersContrast() {
+      if (this.chooseList.length > 1) {
+        this.parametersDisplay = true;
+      }
+    },
+    handleWindturbineChange() {
+        let ws = MessageBridge.getInstance();
+        let wind = [
+            { key: "/topic/windturbine", action: this.getWindMsg },
+        ];
+        let guangfu = [
+            { key: "/topic/pv", action: this.getPvMsg },
+        ];
+        ws.register(wind);
+        ws.register(guangfu);
+    },
+    getPvMsg(msg) {
+        window.sessionStorage.removeItem('pvSbq')
+        // let jsonMsg = JSON.parse(msg)
+        window.sessionStorage.setItem('pvSbq', msg)
+        this.changeData()
+    },
+    getWindMsg(msg) {
+        window.sessionStorage.removeItem('windSbq')
+        // let jsonMsg = JSON.parse(msg)
+        window.sessionStorage.setItem('windSbq', msg)
+        this.changeData()
+    },
+    changeData() {
+        let wswind = JSON.parse(window.sessionStorage.getItem('windSbq'))
+        let pv = JSON.parse(window.sessionStorage.getItem('pvSbq'))
+        let msg = {}
+        if (wswind || pv) {
+            msg = {...wswind}
+            if(pv){
+              msg = {...msg, ...pv}
             }
-          });
-          if (val.lockValue === 9) {
-            val.lockValues = this.lockValues.filter(
-              (item) => val.windturbineId === item.windturbineID
-            )[0]?.value;
-          }
-          this.dataList.push(val);
-          switch (Number(this.selectValue)) {
-            case 0:
-              if (
-                val.status === 5 ||
-                val.status === 6 ||
-                val.status === 7 ||
-                val.lockValue > 0
-              ) {
-                this.showList.push(val);
+            this.windturbinelist = msg;
+            this.$store.commit("windturbinelist", msg);
+            this.dataList = [];
+            const showList = [];
+            let arr = Object.keys(msg).sort();
+            let newArr = [];
+            for (let id of arr) {
+                let val = msg[id];
+                newArr.push(val);
+                this.chooseList.forEach((item) => {
+                if (item.windturbineId === val.windturbineId) {
+                    val.active = true;
+                }
+                });
+                if (val.lockValue === 9) {
+                val.lockValues = this.lockValues.filter(
+                    (item) => val.windturbineId === item.windturbineID
+                )[0]?.value;
+                }
+                this.dataList.push(val);
+                switch (Number(this.selectValue)) {
+                case 0:
+                    if (
+                    val.status === 5 ||
+                    val.status === 6 ||
+                    val.status === 7 ||
+                    val.lockValue > 0
+                    ) {
+                    showList.push(val);
+                    }
+                    break;
+                case 1:
+                    val.status === 5 ? showList.push(val) : "";
+                    break;
+                case 2:
+                    val.status === 6 ? showList.push(val) : "";
+                    break;
+                case 3:
+                    val.status === 7 ? showList.push(val) : "";
+                    break;
+                case 4:
+                    val.lockValue > 0 ? showList.push(val) : "";
+                    break;
+
+                default:
+                    // if (
+                    // val.stationId ===
+                    // this.options.filter(
+                    //     (ops) => ops?.value === this.selectValue
+                    // )[0].stationId
+                    // ) {
+                    // this.showList.push(val);
+                    // }
+                    if (Number(this.selectValue) < 12) {
+                        if (
+                        val.stationId ===
+                        this.options.filter((ops) => ops?.value === this.selectValue)[0]
+                            .stationId
+                        ) {
+                        showList.push(val);
+                        }
+                    } else {
+                        if (
+                        val.station ===
+                        this.options.filter((ops) => ops?.value === this.selectValue)[0]
+                            .stationId
+                        ) {
+                        showList.push(val);
+                        }
+                    }
+                    break;
+                }
+            }
+            // console.log('showList', this.showList)
+            let checkoutList = BackgroundData.getInstance().checkouts;
+            if (checkoutList.length>0) {
+                checkoutList.forEach((item) => {
+                    let showIndex = null;
+                    showList.forEach((param, index) => {
+                    if (item.windturbineId === param.windturbineId) {
+                        showIndex = index;
+                    }
+                    });
+                    showList.splice(showIndex, 1);
+                });
+            }
+            showList.sort((a,b)=>{
+              let aSubString = '0', bSubString = '0'
+              let aStation = '1', bStation = '2'
+              if(a.windturbineId && b.windturbineId){
+                aSubString = a.windturbineId.substring(a.windturbineId.lastIndexOf('_')+1)
+                bSubString = b.windturbineId.substring(b.windturbineId.lastIndexOf('_')+1)
+
+                aStation = a.windturbineId.substring(0, a.windturbineId.lastIndexOf('_'))
+                bStation = b.windturbineId.substring(0, b.windturbineId.lastIndexOf('_'))
+
+              }else if(a.id && b.id){
+                aSubString = a.id.substring(a.id.lastIndexOf('_')+1)
+                bSubString = b.id.substring(b.id.lastIndexOf('_')+1)
+
+                aStation = a.id.substring(0, a.id.lastIndexOf('_'))
+                bStation = b.id.substring(0, b.id.lastIndexOf('_'))
               }
-              break;
-            case 1:
-              val.status === 5 ? this.showList.push(val) : "";
-              break;
-            case 2:
-              val.status === 6 ? this.showList.push(val) : "";
-              break;
-            case 3:
-              val.status === 7 ? this.showList.push(val) : "";
-              break;
-            case 4:
-              val.lockValue > 0 ? this.showList.push(val) : "";
-              break;
-            case 5:
-              val.windturbineId.substring(0, 2) === "MG"
-                ? this.showList.push(val)
-                : "";
-              break;
-            case 6:
-              val.windturbineId.substring(0, 2) === "NG"
-                ? this.showList.push(val)
-                : "";
-              break;
-            case 7:
-              val.windturbineId.substring(0, 2) === "QG"
-                ? this.showList.push(val)
-                : "";
-              break;
-            case 8:
-              val.windturbineId.substring(0, 2) === "SG"
-                ? this.showList.push(val)
-                : "";
-              break;
-            case 9:
-              val.windturbineId.substring(0, 2) === "XG"
-                ? this.showList.push(val)
-                : "";
-              break;
-          }
+              if(aStation === bStation){
+                return parseInt(aSubString) - parseInt(bSubString)
+              }else{
+                return 0
+              }
+            })
+            this.showList = showList
+            
         }
-        let checkoutList = BackgroundData.getInstance().checkouts;
-        checkoutList.forEach((item) => {
-          let showIndex = null;
-          this.showList.forEach((param, index) => {
-            if (item.windturbineId === param.windturbineId) {
-              showIndex = index;
-            }
-          });
-          this.showList.splice(showIndex, 1);
-        });
-      },
-    },
+    }
+  },
+  unmounted() {
+    clearInterval(this.intervals);
+    this.intervals = null;
   },
 };
 </script>
@@ -874,4 +1045,19 @@ export default {
   top: 2px;
   left: 12px;
 }
+.content::-webkit-scrollbar {
+  /*隐藏滚轮*/
+  display: none;
+}
+.box1 {
+  width: 99%;
+  height: 40px;
+  background-color: rgb(30, 30, 30);
+  margin-top: 2px;
+  text-align: left;
+  line-height: 40px;
+  color: #fff;
+  box-sizing: border-box;
+  padding-left: 20px;
+}
 </style>

+ 34 - 36
src/components/control/controlArea.vue

@@ -1,48 +1,46 @@
 <template>
   <div class="problem">
-    <AreaCard
-      title="控制区"
-      height="60"
-      :current="current"
-      ref="areaCard"
-    ></AreaCard>
+    <AreaCard title="控制区" height="60" :windturbineList="windturbineList" :current="current" ref="areaCard"></AreaCard>
   </div>
 </template>
 
 <script>
-import AreaCard from "./areaCard.vue";
-import BackgroundData from "utils/BackgroundData";
-export default {
-  name: "ProblemArea",
-  components: {
-    AreaCard,
-  },
-  props: {
-    current: {
-      type: Number,
+  import AreaCard from "./areaCard.vue";
+  export default {
+    name: "ProblemArea",
+    components: {
+      AreaCard,
     },
-  },
-  data() {
-    return {
-      ls: {
-        maintain: { key: "维护", value: [] },
-        malfunction: { key: "故障", value: [] },
-        offline: { key: "离线", value: [] },
-        lockd: { key: "挂牌", value: [] },
+    props: {
+      current: {
+        type: Number,
       },
-    };
-  },
-  computed: {},
-  created() {},
-  methods: {
-    control(current) {
-      this.$refs.areaCard.control(current);
+      windturbineList: {
+        type: String,
+      },
+    },
+    data() {
+      return {
+        ls: {
+          maintain: { key: "维护", value: [] },
+          malfunction: { key: "故障", value: [] },
+          offline: { key: "离线", value: [] },
+          lockd: { key: "挂牌", value: [] },
+        },
+      };
+    },
+    computed: {},
+    created() {
     },
-  },
-};
+    methods: {
+      control(current){
+        this.$refs.areaCard.control(current)
+      }
+    }
+  };
 </script>
 <style scoped>
-.problem {
-  height: 100%;
-}
+  .problem {
+    height: 100%;
+  }
 </style>

+ 318 - 0
src/components/control/parametersContrast.vue

@@ -0,0 +1,318 @@
+<template>
+  <el-dialog
+    width="85%"
+    @opened="opened()"
+    @closed="closed()"
+    :show-close="false"
+    class="my-info-dialog"
+  >
+    <template #title>
+      <div style="margin-top: -10px; color: #ffffff">参数对比</div>
+    </template>
+    <div class="body">
+      <div class="title" v-if="labelList.length > 0">
+        <div class="labelList">
+          <div
+            :class="items?.type ? 'label_on' : 'label'"
+            v-for="(items, index) in labelList"
+            :key="index"
+            @click="handleClick(items)"
+          >
+            {{ items.name }}
+          </div>
+        </div>
+      </div>
+
+      <div class="titleList" v-if="dataList.length > 0">
+        <el-table
+          :data="dataList"
+          class="table"
+          width="100%"
+          :header-cell-style="{
+            background: '#000000',
+            color: 'rgb(220,220,220)',
+            padding: '4px',
+            fontSize: '14px',
+            'border-bottom': 'solid 1px black',
+          }"
+          :cell-style="{
+            height: '45px',
+            background: 'rgb(30,30,30)',
+            color: 'rgb(220,220,220)',
+            'line-height': '0px',
+            fontSize: '12px',
+            'border-bottom': '1px solid #000000',
+          }"
+        >
+          <el-table-column
+            v-for="(item, index) in titleList"
+            :key="index"
+            min-width="170"
+            align="center"
+            :label="item.name"
+            @click="showPercent(item)"
+          >
+            <template #default="scope" @click="showPercent(item)">
+              <span @click="showPercent(item)">
+                <div
+                  class="cell"
+                  style="
+                    display: flex;
+                    align-items: center;
+                    justify-content: center;
+                  "
+                >
+                  <div
+                    class="left"
+                    v-if="item.showFlag && index !== 0"
+                    :style="`width:${
+                      (scope?.row.filter((val) => val.name === item.name)[0]
+                        ?.value /
+                        item.maxValue) *
+                      95
+                    }%;position: absolute;left: 10px;`"
+                  ></div>
+                  <div style="position: absolute">
+                    {{
+                      index === 0
+                        ? scope?.row.filter((val) => val.name === item.name)[0]
+                            ?.value
+                        : scope?.row
+                            .filter((val) => val.name === item.name)[0]
+                            ?.value?.toFixed(2)
+                    }}
+                  </div>
+                </div>
+              </span>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </div>
+  </el-dialog>
+</template>
+<script>
+import api from "api/index";
+export default {
+  props: {
+    chooseList: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+  },
+  data() {
+    return {
+      dataList: [],
+      labelList: [],
+      allData: {},
+      arrList: [],
+      titleList: [],
+      // intervals: null,
+    };
+  },
+  methods: {
+    opened() {
+      this.dataList = [];
+      this.getCompared();
+      // this.intervals = setInterval(this.getCompared, 5000);
+    },
+    getCompared() {
+      this.labelList = [
+        {
+          name: "全部",
+        },
+      ];
+      let arr = [];
+      this.chooseList.forEach((item) => {
+        let obj = `${item.stationId}.${item.modelId}`;
+        arr.push(obj);
+      });
+      let list = Array.from(new Set(arr));
+      let params = list.join(",");
+      api.stationCompared(params).then((res) => {
+        if (res) {
+          this.arrList = res.data[list[0]];
+          this.allData = res.data;
+          this.labelList = [...this.labelList, ...res.data[list[0]]];
+          this.labelList.forEach((item) => {
+            item.type = true;
+          });
+          this.titleList = JSON.parse(JSON.stringify(this.labelList));
+          this.titleList[0].name = "风机";
+          this.getLatest(0);
+        }
+      });
+    },
+    getLatest(index) {
+      let list = [];
+
+      let arr = this.arrList.map((item) => {
+        return {
+          ...item,
+        };
+      });
+      this.titleList.forEach((item, index) => {
+        if (index !== 0) {
+          arr.filter((val) => val.name === item.name)[0].type = true;
+        }
+      });
+      arr.map((item) => {
+        if (this.labelList.filter((val) => val.name === item.name)[0]?.type) {
+          list.push(item.code);
+        }
+      });
+      arr.unshift({
+        name: "风机",
+        value: this.chooseList[index].windturbineId,
+      });
+      let params = list.join(",");
+      api
+        .nitWinturbineBaseData({
+          thingType: "windturbine",
+          thingId: this.chooseList[index].windturbineId,
+          uniformCodes: params,
+        })
+        .then((res) => {
+          if (res) {
+            arr.forEach((item) => {
+              if (item.type) {
+                item.value = res.data[item.code]?.value;
+              }
+            });
+            this.dataList.push(arr);
+            if (index < this.chooseList.length - 1) {
+              index++;
+              this.getLatest(index);
+            } else {
+              this.titleList.forEach((item, index) => {
+                if (index > 0) {
+                  let datas = [];
+                  this.dataList.map((items) => {
+                    datas.push(
+                      items.filter((val) => item.name === val.name)[0]?.value
+                    );
+                  });
+                  item.maxValue = Math.max.apply(
+                    null,
+                    datas.map((v) => v)
+                  );
+                  item.showFlag = false;
+                }
+              });
+            }
+          }
+        });
+    },
+    closed() {
+      this.labelList = [];
+      this.dataList = [];
+      this.allData = {};
+      this.arrList = [];
+      // clearInterval(this.intervals);
+      // this.intervals = null;
+    },
+    handleClick(value) {
+      this.dataList = [];
+      this.titleList = [];
+      let titleList = [
+        {
+          name: "风机",
+          type: true,
+        },
+      ];
+      if (value.name === "全部") {
+        if (value.type) {
+          this.labelList.forEach((item) => {
+            item.type = false;
+          });
+        } else {
+          this.labelList.forEach((item) => {
+            item.type = true;
+          });
+        }
+      } else {
+        value.type = !value.type;
+      }
+      this.labelList.forEach((item) => {
+        if (item.type && item.name !== "全部") {
+          titleList.push(item);
+        }
+      });
+      this.titleList = JSON.parse(JSON.stringify(titleList));
+      this.getLatest(0);
+    },
+    showPercent(item) {
+      item.showFlag = !item.showFlag;
+    },
+  },
+};
+</script>
+<style scoped>
+.body {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  height: 62vh;
+  overflow-y: auto;
+}
+.title {
+  /* height: 300px; */
+}
+.labelList {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+}
+.label {
+  border: 1px solid #999999;
+  padding: 2px 4px;
+  margin: 0 10px 10px 0;
+  color: #999999;
+}
+.label_on {
+  border: 1px solid rgba(37, 116, 219, 1);
+  background-color: rgba(37, 116, 219, 1);
+  color: #ffffff;
+  padding: 2px 4px;
+  margin: 0 10px 10px 0;
+}
+.titleList {
+  width: 100%;
+}
+.left {
+  height: 20px;
+  background: linear-gradient(
+    to right,
+    rgba(37, 116, 219, 1),
+    rgba(37, 116, 219, 0.6)
+  );
+}
+.table {
+  background-color: #000000 !important;
+}
+
+.el-table td,
+.el-table th.is-leaf {
+  border-bottom: 1px solid #000000 !important;
+}
+
+.el-table__header {
+  width: 100% !important;
+}
+
+.el-table__body-wrapper {
+  background-color: #000000 !important;
+}
+
+.el-table::before {
+  width: 0;
+}
+.el-table__body-wrapper is-scrolling-left {
+  height: 90% !important;
+}
+/* .el-table--scrollable-y ::-webkit-scrollbar {
+  display: none;
+} */
+</style>

Diferenças do arquivo suprimidas por serem muito extensas
+ 5 - 6
src/components/dataDetails.vue


+ 849 - 0
src/components/eaxyMatrixBlock.vue

@@ -0,0 +1,849 @@
+<template>
+  <div class="box" style="display: flex; flex-direction: row; flex-wrap: wrap">
+    <div
+      :class="
+        item.active
+          ? 'box-' + item.status
+          : item.flashing && item.status === 5
+          ? 'unbox-flashing-' + item.status
+          : 'unbox-' + item.status
+      "
+      :id="item.windturbineId"
+      v-for="(item, index) in dataList"
+      :key="index"
+      @click="onSelectHandler(item)"
+      @dblclick="sendMsg(item)"
+    >
+      {{ item.windturbineId }}
+    </div>
+  </div>
+</template>
+<script>
+import dayjs from "dayjs";
+export default {
+  components: {},
+  props: {
+    dataList: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    area: String,
+  },
+  mounted() {},
+  updated() {},
+  methods: {
+    handleDeal(val) {
+      let data = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
+      this.showVlaues = this.timeFn(data);
+      // return `该状态共持续:`
+    },
+
+    timeFn(d1) {
+      //di作为一个变量传进来
+      //如果时间格式是正确的,那下面这一步转化时间格式就可以不用了
+      var dateBegin = new Date(d1.replace(/-/g, "/")); //将-转化为/,使用new Date
+      var dateEnd = new Date(); //获取当前时间
+      var dateDiff = dateEnd.getTime() - dateBegin.getTime(); //时间差的毫秒数
+      var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000)); //计算出相差天数
+      var leave1 = dateDiff % (24 * 3600 * 1000); //计算天数后剩余的毫秒数
+      var hours = Math.floor(leave1 / (3600 * 1000)); //计算出小时数
+      //计算相差分钟数
+      var leave2 = leave1 % (3600 * 1000); //计算小时数后剩余的毫秒数
+      var minutes = Math.floor(leave2 / (60 * 1000)); //计算相差分钟数
+      //计算相差秒数
+      var leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数
+      var seconds = Math.round(leave3 / 1000);
+      return `持续时长:${dayDiff !== 0 ? dayDiff + "天" : ""}${
+        hours !== 0 ? hours + "小时" : ""
+      }${minutes !== 0 ? minutes + "分钟" : ""}${
+        seconds !== 0 ? seconds + "秒" : ""
+      }`;
+    },
+
+    onSelectHandler(values) {
+      if (this.area === "problem") {
+        this.$emit("problem-click", values);
+      } else {
+        this.$emit("choose-click", values);
+      }
+    },
+
+    sendMsg: function (itm) {
+      // this.dialogVisible = true;
+      this.$emit("on-click", itm);
+      // this.currentWindturbine = itm;
+    },
+    handleClose() {
+      this.dialogVisible = false;
+      this.showSvg = false;
+    },
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      showSvg: false,
+      currentWindturbine: {},
+      showVlaues: "",
+      // station: [],
+      options: {
+        8: "检修",
+        7: "故障维修",
+        2: "场内受累检修",
+        3: "场内受累故障",
+        4: "场外受累电网",
+        5: "场外受累天气",
+      },
+    };
+  },
+};
+</script>
+<style scoped>
+.lock {
+  width: 10px;
+  height: 10px;
+  position: relative;
+  right: 2px;
+  top: -15px;
+}
+
+.durationImg {
+  width: 15px;
+  height: 15px;
+  position: relative;
+  right: 5px;
+  top: -15px;
+}
+.durationImgs {
+  width: 15px;
+  height: 15px;
+  position: relative;
+  right: 5px;
+  top: -15px;
+}
+.lock-on {
+  width: 0px;
+  height: 0px;
+  opacity: 0;
+}
+
+.locks:hover .lock-on {
+  position: fixed;
+  display: flex;
+  align-items: center;
+  width: 80px;
+  height: 30px;
+  border: 1px solid #999999;
+  background-color: #999999;
+  opacity: 1;
+  color: #ffffff;
+  z-index: 999;
+}
+
+.duration {
+  width: 15px;
+  height: 15px;
+  position: relative;
+  visibility: hidden;
+}
+.unbox-1:hover .duration {
+  visibility: visible;
+}
+.unbox-2:hover .duration {
+  visibility: visible;
+}
+.unbox-3:hover .duration {
+  visibility: visible;
+}
+.unbox-4:hover .duration {
+  visibility: visible;
+}
+.unbox-5:hover .duration {
+  visibility: visible;
+}
+.unbox-6:hover .duration {
+  visibility: visible;
+}
+.unbox-7:hover .duration {
+  visibility: visible;
+}
+
+.lock_input {
+  width: 140px;
+  background-color: #292929;
+  height: 40px;
+  color: #ffffff;
+}
+.lock_inputs {
+  width: 200px;
+  background-color: #292929;
+  height: 40px;
+  color: #ffffff;
+}
+.box-0 {
+  width: 117px;
+  height: 20px;
+  color: #ffffff;
+  border: 1px solid rgba(255, 255, 255, 1);
+  background-color: rgba(255, 255, 255, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #ffffff;
+  justify-content: center;
+}
+
+.unbox-0 {
+  width: 117px;
+  height: 50px;
+  color: #ffffff;
+  font-size: 12px;
+  border: 1px solid rgba(255, 255, 255, 1);
+  background-color: rgba(255, 255, 255, 0.2);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  border-radius: 0.37vh;
+}
+
+.left-0 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(255, 255, 255, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-0 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(255, 255, 255, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-0 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(255, 255, 255, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-0 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  /* color: rgba(255, 255, 255, 1); */
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  font-size: 12px;
+  color: rgba(255, 255, 255, 1);
+}
+
+.box-1 {
+  width: 117px;
+  height: 20px;
+  color: rgba(197, 48, 200, 1);
+  border: 1px solid rgba(197, 48, 200, 1);
+  background-color: rgba(197, 48, 200, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #ef3af2;
+  justify-content: center;
+}
+
+.unbox-1 {
+  width: 117px;
+  height: 20px;
+  color: rgba(197, 48, 200, 1);
+  font-size: 12px;
+  justify-content: center;
+  border: 1px solid rgba(197, 48, 200, 1);
+  background-color: rgba(197, 48, 200, 0.2);
+  display: flex;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  border-radius: 0.37vh;
+}
+
+.left-1 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(197, 48, 200, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-1 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(197, 48, 200, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-1 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(197, 48, 200, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-1 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(197, 48, 200, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-2 {
+  width: 117px;
+  height: 20px;
+  color: rgba(05, 187, 76, 1);
+  border: 1px solid rgba(05, 187, 76, 1);
+  background-color: rgba(05, 187, 76, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #09e45e;
+  justify-content: center;
+}
+
+.unbox-2 {
+  width: 117px;
+  height: 20px;
+  color: rgba(05, 187, 76, 1);
+  font-size: 12px;
+  border: 1px solid rgba(05, 187, 76, 1);
+  background-color: rgba(05, 187, 76, 0.2);
+  display: flex;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  justify-content: center;
+  border-radius: 0.37vh;
+}
+
+.left-2 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-2 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-2 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-2 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-3 {
+  width: 117px;
+  height: 20px;
+  color: rgba(05, 187, 76, 1);
+  border: 1px solid rgba(05, 187, 76, 1);
+  background-color: rgba(05, 187, 76, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #09e45e;
+  justify-content: center;
+}
+
+.unbox-3 {
+  width: 117px;
+  height: 20px;
+  color: rgba(05, 187, 76, 1);
+  font-size: 12px;
+  border: 1px solid rgba(05, 187, 76, 1);
+  background-color: rgba(05, 187, 76, 0.2);
+  display: flex;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  justify-content: center;
+  border-radius: 0.37vh;
+}
+
+.left-3 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-3 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-3 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-3 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-4 {
+  width: 117px;
+  height: 20px;
+  color: rgba(75, 85, 174, 1);
+  border: 1px solid rgba(75, 85, 174, 1);
+  background-color: rgba(75, 85, 174, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #6876f2;
+  justify-content: center;
+}
+
+.unbox-4 {
+  width: 117px;
+  height: 20px;
+  /* color: #ffffff; */
+  border: 1px solid rgba(75, 85, 174, 1);
+  background-color: rgba(75, 85, 174, 0.2);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  border-radius: 0.37vh;
+}
+
+.left-4 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-4 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-4 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-4 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-5 {
+  width: 117px;
+  height: 20px;
+  color: rgba(186, 50, 55, 1);
+  border: 2px solid rgba(186, 50, 55, 1);
+  background-color: rgba(186, 50, 55, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #ff1313;
+  justify-content: center;
+}
+
+@keyframes fade {
+  from {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0.6;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes fade {
+  from {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0.6;
+  }
+  to {
+    opacity: 1;
+  }
+}
+
+.unbox-flashing-5 {
+  width: 117px;
+  height: 20px;
+  color: #ffffff;
+  border: 1px solid rgba(186, 50, 55, 1);
+  background-color: rgba(186, 50, 55, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  animation: fade 1600ms infinite;
+  -webkit-animation: fade 1600ms infinite;
+  border-radius: 0.37vh;
+}
+
+.unbox-5 {
+  width: 117px;
+  height: 20px;
+  color: rgba(186, 50, 55, 1);
+  font-size: 12px;
+  border: 1px solid rgba(186, 50, 55, 1);
+  background-color: rgba(186, 50, 55, 0.2);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  border-radius: 0.37vh;
+}
+
+.left-5 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-5 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-5 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-5 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-6 {
+  width: 117px;
+  height: 20px;
+  color: rgba(225, 125, 36, 1);
+  border: 1px solid rgba(225, 125, 36, 1);
+  background-color: rgba(225, 125, 36, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #f28627;
+  justify-content: center;
+}
+
+.unbox-6 {
+  width: 117px;
+  height: 20px;
+  color: rgba(225, 125, 36, 1);
+  font-size: 12px;
+  border: 1px solid rgba(225, 125, 36, 1);
+  background-color: rgba(225, 125, 36, 0.2);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  border-radius: 0.37vh;
+}
+
+.left-6 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-6 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-6 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-6 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-7 {
+  width: 117px;
+  height: 20px;
+  color: rgba(96, 103, 105, 1);
+  border: 1px solid rgba(96, 103, 105, 1);
+  background-color: rgba(96, 103, 105, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #ffffff;
+  justify-content: center;
+}
+
+.unbox-7 {
+  width: 117px;
+  height: 20px;
+  color: rgba(96, 103, 105, 1);
+  font-size: 12px;
+  border: 1px solid rgba(96, 103, 105, 1);
+  background-color: rgba(96, 103, 105, 0.2);
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  border-radius: 0.37vh;
+}
+
+.left-7 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(96, 103, 105, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-7 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(96, 103, 105, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-7 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(96, 103, 105, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-7 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(96, 103, 105, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+</style>

+ 2 - 7
src/components/focus/PhotoelectricDetailPages.vue

@@ -4,7 +4,6 @@
 			<div class="showTitle">
 				<img class="titleImg" src="../../assets/img/controlcenter/daraTrue.png" alt="">
 				<div class="titles">{{stationName}}</div>
-				<!-- <div class="icon">(麻黄山)</div> -->
 			</div>
 		</template>
 		<div class="body">
@@ -91,10 +90,6 @@
 </template>
 
 <script>
-	// import UniformCodes from "../../assets/script/UniformCodes";
-	// import { config } from '../../config';
-	// import axios from 'axios';
-	// import BackgroundData from "../../assets/script/BackgroundData"
 	import MultipleLineChart from "./multiple-line-chart.vue";
 	import dayjs from 'dayjs'
 	export default {
@@ -145,13 +140,13 @@
 				}
 				PowerSet.forEach(item => {
 					this.chartData.value[0].value.push({
-						text: dayjs(item.ts).format('hh:mm'),
+						text: dayjs(item.ts).format('HH:mm'),
 						value: parseFloat((item.doubleValue).toFixed(2))
 					})
 				})
 				ActualPower.forEach(item => {
 					this.chartData.value[1].value.push({
-						text: dayjs(item.ts).format('hh:mm'),
+						text: dayjs(item.ts).format('HH:mm'),
 						value: parseFloat((item.doubleValue).toFixed(2))
 					})
 				})

+ 41 - 90
src/components/focus/agcDetails.vue

@@ -12,7 +12,7 @@
         <div class="titles">AGC监控</div>
       </div>
     </template>
-    <div class="bodyy">
+    <div class="bodyy currentScroll">
       <DataDetails
         ref="detailst"
         :allDate="allDate"
@@ -31,8 +31,8 @@
 <script>
 import DataDetails from "./dataDetails";
 import DetailsCharts from "./detailsCharts";
-// import { Photoelectric } from "utils/PhotoelectricDetailPages";
 import api from "api/index";
+import dayjs from "dayjs";
 export default {
   components: {
     DataDetails,
@@ -40,62 +40,27 @@ export default {
   },
   data() {
     return {
-      Photoelectric: null,
-      station: [
-        {
-          id: "MHS_BT",
-          name: "麻黄山第二风电场",
-          names: "麻黄山",
-        },
-
-        {
-          id: "NSS_BT",
-          name: "牛首山第二风电场",
-          names: "牛首山",
-        },
-        {
-          id: "QS_BT",
-          name: "麻黄山第六风电场",
-          names: "青山",
-        },
-        {
-          id: "XN6_BT",
-          name: "星能第六风电场",
-          names: "石板泉一期",
-        },
-        {
-          id: "N5_BT",
-          name: "牛首山第五风电场",
-          names: "二三四期",
-        },
-        {
-          id: "XS_BT",
-          name: "香山第五风电场",
-          names: "香山",
-        },
-        {
-          id: "SL_BT",
-          name: "宋堡第六风电场",
-          names: "青山三期",
-        },
-      ],
+      station: [],
       allDate: {},
       allChartDate: [],
       detailsDisplay: false,
       showData: {},
+      intervals: "",
     };
   },
-  mounted() {},
-  updated() {
-    if (this.Photoelectric) {
-      this.getLatest(0);
-      this.getChartData(0);
-    }
+  created() {
+    this.getAGCStation();
   },
+  updated() {},
   methods: {
+    getAGCStation() {
+      api.getAGCStation().then((res) => {
+        this.station = res.data;
+      });
+    },
     getLatest(index) {
       let dialogData = {};
-      let thisKey = this.Photoelectric[this.station[index].id];
+      let thisKey = this.station[index].tags;
       let array = [];
       thisKey.forEach((item) => {
         item.value ? array.push(item.value) : "";
@@ -110,23 +75,26 @@ export default {
                 name: item.name,
                 value: res.data[v].doubleValue
                   ? res.data[v].doubleValue === 0
-                    ? "0"
-                    : (res.data[v].doubleValue * calc).toFixed(2)
-                  : res.data[v].booleanValue
+                    ? 0
+                    : Number((res.data[v].doubleValue * calc).toFixed(2))
+                  : Number(res.data[v].booleanValue)
                   ? 1
                   : 0,
+                tag: item.value,
+                calc: item.calc,
               };
             }
           });
         }
         this.allDate[this.station[index].id] = dialogData;
-        this.allDate[this.station[index].id].InstalledCapacity =
-          this.Photoelectric[this.station[index].id].find((ele) => {
-            return ele.tag == "InstalledCapacity";
-          });
+        this.allDate[this.station[index].id].InstalledCapacity = this.station[
+          index
+        ].tags.find((ele) => {
+          return ele.tag == "InstalledCapacity";
+        });
         index++;
         if (index >= this.station.length) {
-          setTimeout(() => {
+          this.intervals = setTimeout(() => {
             this.getLatest(0);
           }, 3000);
         } else {
@@ -134,12 +102,12 @@ export default {
         }
       });
     },
-
     getChartData(index) {
-      let thisKey = this.Photoelectric[this.station[index].id];
-      let date = new Date();
-      let endTs = date.getTime();
-      let starTs = endTs - 28800000;
+      let thisKey = this.station[index].tags;
+      let endTs = new Date().getTime();
+      let starTs = new Date(
+        new Date(new Date().toLocaleDateString()).getTime()
+      ).getTime();
       let chartData = {
         value: [],
       };
@@ -191,14 +159,14 @@ export default {
               };
               PowerSetData.forEach((item) => {
                 chartData.value[0].value.push({
-                  text: dayjs(item.ts).format("hh:mm"),
-                  value: parseFloat(item.doubleValue.toFixed(2)),
+                  text: dayjs(item.ts).format("HH:mm"),
+                  value: parseFloat(Number(item.doubleValue).toFixed(2)),
                 });
               });
               ActualPowerData.forEach((item) => {
                 chartData.value[1].value.push({
-                  text: dayjs(item.ts).format("hh:mm"),
-                  value: parseFloat(item.doubleValue.toFixed(2)),
+                  text: dayjs(item.ts).format("HH:mm"),
+                  value: parseFloat(Number(item.doubleValue).toFixed(2)),
                 });
               });
               chartData.id = this.station[index].id;
@@ -217,24 +185,13 @@ export default {
         });
     },
     opened() {
-      api.getStation().then((res) => {
-        let Photoelectric = {};
-        res.data.forEach((pEle) => {
-          Photoelectric[pEle.id] = [];
-          pEle.tags.forEach((cEle) => {
-            let item = {};
-            for (let key in cEle) {
-              item[key] = String(cEle[key]);
-            }
-            Photoelectric[pEle.id].push(item);
-          });
-        });
-        this.Photoelectric = Photoelectric;
-        this.getLatest(0);
-        this.getChartData(0);
-      });
+      this.getLatest(0);
+      this.getChartData(0);
+    },
+    closed() {
+      clearInterval(this.intervals);
+      this.intervals = null;
     },
-    closed() {},
     handleClicks(id) {
       this.showData = this.allChartDate.find((ele) => {
         return ele.id == id;
@@ -251,19 +208,13 @@ export default {
 };
 </script>
 
-<style lang="less" scoped>
+<style scoped>
 .bodyy {
   display: flex;
   flex-direction: row;
   background-color: black;
   width: 100%;
   margin-top: -30px;
-  height: 89vh;
-  .body {
-    height: 100%;
-    max-height: 100%;
-    overflow-x: hidden;
-    overflow-y: hidden;
-  }
+  min-height: 90vh;
 }
 </style>

+ 34 - 32
src/components/focus/currentWarningCard.vue

@@ -47,8 +47,8 @@ export default {
   name: "AlarmArea",
   components: {},
   created() {
-    this.initData();
     this.faultMessage();
+    this.intervals = setInterval(this.faultMessage, 15000);
   },
   props: {
     activeTab: {
@@ -67,6 +67,7 @@ export default {
       stationName: "",
       currentWindturbine: {},
       audio: null,
+      intervals: null,
     };
   },
   methods: {
@@ -92,40 +93,37 @@ export default {
 
       this.tableData = [].concat(syzAlarm, syzBase);
     },
-    initData() {
-      let mb = MessageBridge.getInstance();
-      let vs = [
-        {
-          key: "/topic/fault-popup",
-          action: this.faultMessage,
-        },
-      ];
-      mb.register(vs);
-    },
     faultMessage(json) {
-      let val = json ? JSON.parse(json) : this.$store.state.warning;
-      if (Object.keys(val).length > 0) {
-        let sleected = {};
-        this.values.forEach((it) => {
-          if (it.isSelected) {
-            sleected[it.id] = 0;
-          }
-        });
-        this.values = new Array();
-        for (let v in val) {
-          let vl = val[v];
-          if (vl.stationId != "QS_FDC" && vl.category1 == "FJ") {
-            vl.alertText = vl.windturbineName + "-" + vl.alertText;
-          }
-          if (sleected[vl.id] == 0 && BackgroundData.getInstance().LoginUser) {
-            vl.isSelected = true;
-          }
-          if (vl.category1 !== "GF" && vl.objectId.indexOf("GDC") === -1) {
-            this.values.push(vl);
+      api.alarmFault().then((res) => {
+        if (res.data) {
+          let val = res.data;
+          if (Object.keys(val).length > 0) {
+            let sleected = {};
+            this.values.forEach((it) => {
+              if (it.isSelected) {
+                sleected[it.id] = 0;
+              }
+            });
+            this.values = new Array();
+            for (let v in val) {
+              let vl = val[v];
+              if (vl.stationId != "QS_FDC" && vl.category1 == "FJ") {
+                vl.alertText = vl.windturbineName + "-" + vl.alertText;
+              }
+              if (
+                sleected[vl.id] == 0 &&
+                BackgroundData.getInstance().LoginUser
+              ) {
+                vl.isSelected = true;
+              }
+              if (vl.category1 !== "GF" && vl.objectId.indexOf("GDC") === -1) {
+                this.values.push(vl);
+              }
+            }
+            this.filtrationData(this.activeTab);
           }
         }
-        this.filtrationData(this.activeTab);
-      }
+      });
     },
     close() {
       this.dialogVisible = false;
@@ -181,6 +179,10 @@ export default {
       }
     },
   },
+  unmounted() {
+    clearInterval(this.intervals);
+    this.intervals = null;
+  },
   watch: {
     activeTab(res) {
       this.filtrationData(res);

+ 143 - 15
src/components/focus/dataDetails.vue

@@ -7,9 +7,14 @@
     >
       <div class="stationName">
         <div class="titleName">{{ item.name }}</div>
-        <div class="titleNames">({{ item.names }})</div>
+        <div class="titleNames" v-if="item.schedulingName">
+          ({{ item.schedulingName }})
+        </div>
         <img
-          v-if="allDate[item.id]?.Status?.value === 0"
+          v-if="
+            !allDate[item.id]?.Status?.value ||
+            allDate[item.id]?.Status?.value === 0
+          "
           class="statusIcons"
           src="../../assets/img/controlcenter/daraTrue.png"
         />
@@ -18,7 +23,13 @@
           class="statusIcons"
           src="../../assets/img/controlcenter/dataFalse.png"
         />
-        <div class="titleNames" v-if="allDate[item.id]?.Status?.value !== 0">
+        <div
+          class="titleNames"
+          v-if="
+            allDate[item.id]?.Status?.value &&
+            allDate[item.id]?.Status?.value !== 0
+          "
+        >
           {{
             (
               (1 -
@@ -30,35 +41,50 @@
         </div>
       </div>
       <div class="dataList">
-        <div class="data">
+        <div
+          class="data"
+          @dblclick="dbClicks(allDate[item.id]?.PowerSet, '有功设定限值')"
+        >
           <div class="name">有功设定限值:</div>
           <div :class="index < 3 ? 'nums' : 'nums'">
             {{ allDate[item.id]?.PowerSet?.value ?? 0 }}
           </div>
           <div class="unit">MW</div>
         </div>
-        <div class="data">
+        <div
+          class="data"
+          @dblclick="dbClicks(allDate[item.id]?.ActualPower, '实发有功')"
+        >
           <div class="name">实发有功:</div>
           <div :class="index < 3 ? 'nums' : 'nums'">
             {{ allDate[item.id]?.ActualPower?.value ?? 0 }}
           </div>
           <div class="unit">MW</div>
         </div>
-        <div class="data">
+        <div
+          class="data"
+          @dblclick="dbClicks(allDate[item.id]?.AgcUp, 'AGC可调上限')"
+        >
           <div class="name">AGC可调上限:</div>
           <div :class="index < 3 ? 'nums' : 'nums'">
             {{ allDate[item.id]?.AgcUp?.value ?? 0 }}
           </div>
           <div class="unit">MW</div>
         </div>
-        <div class="data">
+        <div
+          class="data"
+          @dblclick="dbClicks(allDate[item.id]?.TheoryPower, '理论功率')"
+        >
           <div class="name">理论功率:</div>
           <div :class="index < 3 ? 'nums' : 'nums'">
             {{ allDate[item.id]?.TheoryPower?.value ?? 0 }}
           </div>
           <div class="unit">MW</div>
         </div>
-        <div class="data">
+        <div
+          class="data"
+          @dblclick="dbClicks(allDate[item.id]?.AgcLower, 'AGC可调下限')"
+        >
           <div class="name">AGC可调下限:</div>
           <div :class="index < 3 ? 'nums' : 'nums'">
             {{ allDate[item.id]?.AgcLower?.value ?? 0 }}
@@ -66,7 +92,10 @@
           <div class="unit">MW</div>
         </div>
 
-        <div class="data">
+        <div
+          class="data"
+          @dblclick="dbClicks(allDate[item.id]?.ForecastPower, '预测功率')"
+        >
           <div class="name">预测功率:</div>
           <div :class="index < 3 ? 'nums' : 'nums'">
             {{ allDate[item.id]?.ForecastPower?.value ?? 0 }}
@@ -136,15 +165,35 @@
           </div>
         </div>
       </div>
-      <div :id="item.id" class="echarts" @click="handleClick(item.id)"></div>
+      <div :id="item.id" class="echarts" @dblclick="handleClick(item.id)"></div>
     </div>
+
+    <Details
+      @closed="closed()"
+      v-model="display"
+      :partsName="partsName"
+      echartsId="modelEcharts"
+      :datas="modelDetails"
+      :calc="this.modelData.calc"
+      @search-data="search"
+      @original-data="originalData"
+    ></Details>
   </div>
 </template>
 <script>
 import * as echarts from "echarts";
+import Details from "../basicDataDetails.vue";
+import api from "api/index";
 export default {
+  components: {
+    Details,
+  },
   data() {
-    return {};
+    return {
+      display: false,
+      modelData: {},
+      partsName: "",
+    };
   },
   props: {
     allDate: {
@@ -169,12 +218,74 @@ export default {
   },
   mounted() {},
   methods: {
+    dbClicks(data, partsName, timeValues) {
+      this.modelData = data;
+      let date = new Date();
+      let endTs = timeValues
+        ? timeValues[1] > date.getTime()
+          ? date.getTime()
+          : timeValues[1]
+        : date.getTime();
+      let startTs = timeValues ? timeValues[0] : endTs - 28800000;
+      data.tag &&
+        api
+          .getPower({
+            tagName: data.tag,
+            startTs: startTs,
+            endTs: endTs,
+            interval: 60,
+          })
+          .then((res) => {
+            if (res.data.length > 0) {
+              this.partsName = partsName;
+              this.display = true;
+              this.modelDetails = res.data;
+            } else {
+              this.modelDetails = [];
+            }
+          });
+    },
+    original(data, partsName, timeValues) {
+      this.modelData = data;
+      let date = new Date();
+      let endTs = timeValues
+        ? timeValues[1] > date.getTime()
+          ? date.getTime()
+          : timeValues[1]
+        : date.getTime();
+      let startTs = timeValues ? timeValues[0] : endTs - 28800000;
+      api
+        .getOriginalPower({
+          tagName: data.tag,
+          startTs: startTs,
+          endTs: endTs,
+        })
+        .then((res) => {
+          if (res.data.length > 0) {
+            this.partsName = partsName;
+            this.display = true;
+            this.modelDetails = res.data;
+          } else {
+            this.modelDetails = [];
+          }
+        });
+    },
+    search(values, interval) {
+      this.interval = interval;
+      this.dbClicks(this.modelData, this.partsName, values);
+    },
+    originalData(values) {
+      this.original(this.modelData, this.partsName, values);
+    },
     totleErtcher() {
       this.allChartDate.forEach((item) => {
         let chartDom = document.getElementById(item.id);
         let myChart = echarts.init(chartDom, "#ffffff");
         let option;
         option = {
+          tooltip: {
+            trigger: "axis",
+          },
           legend: {
             show: true,
             data: item.value.map((t) => {
@@ -279,6 +390,16 @@ export default {
     opened() {},
     closed() {
       this.detailsDisplay = false;
+      this.display = false;
+    },
+  },
+  watch: {
+    allChartDate: {
+      handler: function (json) {
+        if (json) {
+          this.totleErtcher();
+        }
+      },
     },
   },
 };
@@ -309,7 +430,7 @@ export default {
 }
 
 .showContents {
-  width: 23.7%;
+  width: 40%;
   display: flex;
   flex-direction: column;
   border: 1px solid rgba(77, 77, 77, 1);
@@ -352,13 +473,20 @@ export default {
   flex-direction: row;
   flex-wrap: wrap;
   justify-content: center;
+  height: 90vh;
+  overflow-y: auto;
+}
+
+.body::-webkit-scrollbar {
+  /*隐藏滚轮*/
+  display: none;
 }
 
 .echarts {
-  width: 110%;
-  height: 290px;
+  width: 100%;
+  height: 500px;
   margin-left: 10px;
-  padding-top: 20px;
+  padding-top: -20px;
 }
 
 .dataList {

+ 151 - 139
src/components/focus/detailsCharts.vue

@@ -1,155 +1,167 @@
 <template>
-    <el-dialog width="70%" @open="opened()" @closed="closed()" :show-close="true" class="dialogs">
-        <template #title>
-            <div class="showTitles">
-                <div class="stationName">
-                    <div class="titleName">{{showData?.name?.name}}</div>
-                    <div class="titleNames">({{showData?.name?.names}})</div>
-                </div>
-            </div>
-        </template>
-        <div class="bodyy">
-            <div id="showEcharts" class="echarts"></div>
+  <el-dialog
+    width="70%"
+    @open="opened()"
+    @closed="closed()"
+    :show-close="true"
+    class="dialogs"
+  >
+    <template #title>
+      <div class="showTitles">
+        <div class="stationName">
+          <div class="titleName">{{ showData?.name?.name }}</div>
+          <div class="titleNames" v-if="showData?.name?.names">
+            ({{ showData?.name?.names }})
+          </div>
         </div>
-    </el-dialog>
+      </div>
+    </template>
+    <div class="bodyy">
+      <div id="showEcharts" class="echarts"></div>
+    </div>
+  </el-dialog>
 </template>
 <script>
-    import * as echarts from "echarts";
-    export default {
-        props: {
-            showData: {
-                type: String,
-                default: ''
-            },
+import * as echarts from "echarts";
+export default {
+  props: {
+    showData: {
+      type: String,
+      default: "",
+    },
+  },
+  updated() {
+    this.showEcharts(this.showData);
+  },
+  methods: {
+    showEcharts(showData) {
+      let chartDom = document.getElementById("showEcharts");
+        chartDom.removeAttribute("_echarts_instance_")
+      let myChart = echarts.init(chartDom, "#ffffff");
+      let option;
+      option = {
+        tooltip: {
+          trigger: "axis",
         },
-        updated() {
-            this.showEcharts(this.showData)
+        legend: {
+          show: true,
+          data: showData.value.map((t) => {
+            return t.title;
+          }),
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: "#606769",
+          textStyle: {
+            color: "#B3BDC0",
+            fontSize: 12,
+          },
         },
-        methods: {
-            showEcharts(showData) {
-                let chartDom = document.getElementById('showEcharts');
-                let myChart = echarts.init(chartDom, '#ffffff');
-                let option;
-                option = {
-					legend: {
-						show: true,
-						data: showData.value.map((t) => {
-							return t.title;
-						}),
-						right: 56,
-						icon: "circle",
-						itemWidth: 6,
-						inactiveColor: '#606769',
-						textStyle: {
-							color: '#B3BDC0',
-							fontSize: 12,
-						},
-					},
-					xAxis: [
-						{
-							type: "category",
-							boundaryGap: false,
-							axisLabel: {
-								interval: 60,
-								showMinLabel: true,
-								showMaxLabel: true,
-								formatter: "{value}",
-								fontSize: 14,
-								textStyle: {
-									color: '#606769',
-								},
-							},
-							axisLine: {
-								show: false,
-							},
-							data: showData.value[0].value.map(item => {
-								return item.text;
-							}),
-						},
-					],
-					yAxis: {
-						type: "value",
-						axisLabel: {
-							formatter: "{value}",
-							fontSize: 14,
-						},
-						axisLine: {
-							show: false,
-						},
-						splitLine: {
-							show: true,
-							lineStyle: {
-								color: '#606769',
-								type: "dashed",
-							},
-						},
-					},
-					series: [{
-						name: showData.value[0].title,
-						smooth: true,
-						showSymbol: false,
-						data: showData.value[0].value.map(item => {
-							return item.value;
-						}),
-						type: 'line',
-						lineStyle: {
-							normal: {
-								color: 'rgba(75, 85, 174, 1)',
-								width: 1,
-							},
-						},
-					},
-					{
-						name: showData.value[1].title,
-						smooth: true,
-						showSymbol: false,
-						data: showData.value[1].value.map(item => {
-							return item.value;
-						}),
-						type: 'line',
-						lineStyle: {
-							normal: {
-								color: 'rgba(05, 187, 76, 1)',
-								width: 1,
-							},
-						},
-					}]
-				};
-                option && myChart.setOption(option);
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              interval: 60,
+              showMinLabel: true,
+              showMaxLabel: true,
+              formatter: "{value}",
+              fontSize: 14,
+              textStyle: {
+                color: "#606769",
+              },
             },
-            opened() {
-
+            axisLine: {
+              show: false,
             },
-            closed() {
-                this.$emit('closeds');
+            data: showData.value[0].value.map((item) => {
+              return item.text;
+            }),
+          },
+        ],
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: 14,
+          },
+          axisLine: {
+            show: false,
+          },
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "#606769",
+              type: "dashed",
             },
+          },
         },
-    }
+        series: [
+          {
+            name: showData.value[0].title,
+            smooth: true,
+            showSymbol: false,
+            data: showData.value[0].value.map((item) => {
+              return item.value;
+            }),
+            type: "line",
+            lineStyle: {
+              normal: {
+                color: "rgba(75, 85, 174, 1)",
+                width: 1,
+              },
+            },
+          },
+          {
+            name: showData.value[1].title,
+            smooth: true,
+            showSymbol: false,
+            data: showData.value[1].value.map((item) => {
+              return item.value;
+            }),
+            type: "line",
+            lineStyle: {
+              normal: {
+                color: "rgba(05, 187, 76, 1)",
+                width: 1,
+              },
+            },
+          },
+        ],
+      };
+      option && myChart.setOption(option);
+    },
+    opened() {},
+    closed() {
+      this.$emit("closeds");
+    },
+  },
+};
 </script>
 <style scoped>
-    .echarts {
-        width: 1300px;
-        height: 60vh;
-    }
+.echarts {
+  width: 1300px;
+  height: 60vh;
+}
 
-    .stationName {
-        font-size: 20px;
-        width: 400px;
-        height: 45px;
-        display: flex;
-        flex-direction: row;
-        align-items: baseline;
-        justify-content: center;
-        color: #FFFFFF;
-    }
+.stationName {
+  font-size: 20px;
+  width: 400px;
+  height: 45px;
+  display: flex;
+  flex-direction: row;
+  align-items: baseline;
+  justify-content: center;
+  color: #ffffff;
+}
 
-    .titleName {
-        margin-top: 10px;
-    }
+.titleName {
+  margin-top: 10px;
+}
 
-    .titleNames {
-        font-size: 12px;
-        margin-left: 10px;
-        margin-top: 10px;
-    }
+.titleNames {
+  font-size: 12px;
+  margin-left: 10px;
+  margin-top: 10px;
+}
 </style>

+ 115 - 21
src/components/focus/focusArea.vue

@@ -1,8 +1,24 @@
 <template>
-  <div class="body">
+  <!-- <div class="body">
     <img class="logo" src="../../assets/img/logo.png" alt="" />
     <div class="title">关注区</div>
     <div class="agc" @click="showAGC">AGC监控</div>
+    <div class="booster" @click="showBooster">升压站监控</div>
+    <div style="margin-top: 50px; margin-left: 10px; height: 24vh">
+      <el-scrollbar>
+        <div class="scoll" style="margin-left: 5px">
+          <FocusCard></FocusCard>
+        </div>
+      </el-scrollbar>
+    </div>
+    <AGCDetails v-model="display"></AGCDetails>
+    <StationSvgDetailPages v-model="displayBooster" @close="close">
+    </StationSvgDetailPages>
+  </div> -->
+  <div class="body">
+    <img class="logo" src="../../assets/img/logo.png" alt="" />
+    <div class="title">关注区</div>
+    <!-- <div class="agc" @click="showAGC">AGC监控</div>
     <el-tooltip
       v-if="$store.state.syzBtnFlicker"
       class="box-item"
@@ -17,8 +33,8 @@
       >
         升压站
       </div>
-    </el-tooltip>
-    <div v-else class="syz" @click="showSYZ">升压站</div>
+    </el-tooltip> -->
+    <!-- <div v-else class="syz" @click="showSYZ">升压站</div> -->
     <div style="margin-top: 50px; margin-left: 10px; height: 24vh">
       <el-scrollbar>
         <div class="scoll" style="margin-left: 5px">
@@ -26,41 +42,119 @@
         </div>
       </el-scrollbar>
     </div>
-    <AGCDetails v-model="display"></AGCDetails>
-    <SYZDetails v-model="$store.state.syzDialogShow"></SYZDetails>
+    <!-- <AGCDetails v-model="display"></AGCDetails>
+    <SYZDetails v-model="$store.state.syzDialogShow"></SYZDetails> -->
   </div>
 </template>
 <script>
 import FocusCard from "./focusCard.vue";
-import AGCDetails from "./agcDetails.vue";
-import SYZDetails from "./syzDetails.vue";
-
-// import boxSelect from "components/boxSelect.vue";
+// import AGCDetails from "./agcDetails.vue";
+// import StationSvgDetailPages from "../stationSvgDetailPages.vue";
+// import SYZDetails from "./syzDetails.vue";
 export default {
   data() {
     return {
       display: false,
-      alarmMsg: "",
+      displayBooster: false,
     };
   },
   components: {
     FocusCard,
-    AGCDetails,
-    SYZDetails,
-    // boxSelect,
+    // AGCDetails,
+    // StationSvgDetailPages,
+    // SYZDetails,
   },
   methods: {
-    showAGC() {
-      this.display = true;
-    },
-
-    showSYZ() {
-      this.$store.commit("syzDialogShow", true);
-    },
+    // showAGC() {
+    //   this.display = true;
+    // },
+    // showBooster() {
+    //   this.displayBooster = true;
+    // },
+    // close() {
+    //   this.displayBooster = false;
+    // },
+    // showSYZ() {
+    //   this.$store.commit("syzDialogShow", true);
+    // },
   },
 };
 </script>
 <style scoped>
+/* .box {
+  width: 100px;
+  height: 20px;
+
+  margin-top: 30px;
+}
+.body {
+  border: 1px solid #373737;
+  width: 100%;
+  margin-left: 15px;
+  margin-top: 10px;
+  height: 30.5vh;
+}
+
+.body .scoll {
+  height: 91%;
+}
+
+.title {
+  color: #ffffff;
+  font-size: 14px;
+  margin-left: 32px;
+  margin-bottom: 10px;
+  width: 29vw;
+  height: 50px;
+  display: flex;
+  align-items: center;
+  position: absolute;
+  background-color: #000000;
+}
+
+.title::before {
+  z-index: 1;
+  content: "";
+  position: absolute;
+  left: -18px !important;
+  width: 5px;
+  height: 5px;
+  background-color: rgba(230, 191, 65, 1);
+  border-radius: 50%;
+}
+
+.logo {
+  position: absolute;
+  top: 2px;
+  left: 12px;
+}
+
+.agc {
+  position: absolute;
+  color: #ffffff;
+  font-size: 14px;
+  right: 0;
+  top: 23px;
+  width: 80px;
+  height: 30px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: rgba(37, 116, 219, 1);
+}
+.booster {
+  position: absolute;
+  color: #ffffff;
+  font-size: 14px;
+  right: 100px;
+  top: 23px;
+  width: 80px;
+  height: 30px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: rgba(37, 116, 219, 1);
+} */
 .body {
   border: 1px solid #373737;
   width: 100%;
@@ -80,7 +174,7 @@ export default {
   /* margin-top: 12px; */
   margin-bottom: 10px;
   /* width: 570px; */
-  width: 29vw;
+  width: 27vw;
   height: 50px;
   display: flex;
   align-items: center;

+ 232 - 263
src/components/focus/focusCard.vue

@@ -1,272 +1,241 @@
 /* 推荐区 */
 <template>
-	<div style="display: flex;justify-content: flex-start;flex-wrap: wrap;">
-		<div class="area" v-for="(vl , index) in values" :key="vl" @dblclick="sendMsg(vl,index)">
-			<img class="imgs" src="../../assets/img/RecommendedArea/background.png" alt="">
-			<div class="content">{{vl.showType}}</div>
-			<div class="">{{vl.name}}</div>
-			<div class="">{{vl.createTime}}</div>
-		</div>
-	</div>
-	<PhotoelectricDetailPages ref="photo" @closed="closed()" :data="dialogData.data"
-		:stationName="dialogData.stationName" v-model="dialogVisible">
-	</PhotoelectricDetailPages>
-	<WindturbineDetailPages v-model="windVisible" :windturbine="currentWindturbine" @close="close">
-	</WindturbineDetailPages>
-	<StationSvgDetailPages v-model="svgVisible" :stationName="stationNames" :svgWeb="svgWeb" @close="close">
-	</StationSvgDetailPages>
+  <div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
+    <div
+      class="area"
+      v-for="(vl, index) in values"
+      :key="vl"
+      @dblclick="sendMsg(vl, flase, index)"
+    >
+      <img
+        class="imgs"
+        src="../../assets/img/RecommendedArea/background.png"
+        alt=""
+      />
+      <div class="content">{{ vl.showType }}</div>
+      <div class="">{{ vl.name }}</div>
+      <div class="">{{ vl.createTime }}</div>
+    </div>
+  </div>
+  <PhotoelectricDetailPages
+    ref="photo"
+    @closed="closed()"
+    :data="dialogData.data"
+    :stationName="dialogData.stationName"
+    v-model="dialogVisible"
+  >
+  </PhotoelectricDetailPages>
+  <WindturbineDetailPages
+    v-model="windVisible"
+    :windturbine="currentWindturbine"
+    @close="close"
+  >
+  </WindturbineDetailPages>
+  <StationSvgDetailPages
+    v-model="svgVisible"
+    :svgWeb="svgWeb"
+    @close="close"
+  >
+  </StationSvgDetailPages>
 </template>
 
 <script>
-	import BackgroundData from "utils/BackgroundData"
-	import { Photoelectric } from "utils/PhotoelectricDetailPages";
-	import PhotoelectricDetailPages from "./PhotoelectricDetailPages.vue"
-	import MessageBridge from 'utils/MessageBridge'
-	import StationSvgDetailPages from "../stationSvgDetailPages.vue";
-	import WindturbineDetailPages from "../WindturbineDetailPages.vue";
-	import api from "api/index";
-	import axios from 'axios';
-	import dayjs from 'dayjs'
-	export default {
-		name: "RecommendedArea",
-		props: ["datas"],
-		data() {
-			return {
-				values: [],
-				currentWindturbine: {},
-				dialogVisible: false,
-				svgVisible: false,
-				windVisible: false,
-				svgWeb: '',
-				stationNames: '',
-				dialogData: {
-					data: {
-						PowerSet: '',
-						AgcUp: '',
-						AgcLower: '',
-						ActualPower: '',
-						TheoryPower: '',
-						ForecastPower: '',
-						AgcIn: '',
-						AgcFar: '',
-						SumLock: '',
-						SubLock: '',
-					}
-				},
-				dataMsg: [],
-				interval: '',
-				arrKey: [],
-				timeIndex: 0
-			};
-		},
-		components: {
-			PhotoelectricDetailPages,
-			StationSvgDetailPages,
-			WindturbineDetailPages,
-		},
-		created() {
-			this.datacontrol();
-			// this.initData();
-		},
-		methods: {
-			datacontrol() {
-				let mb = MessageBridge.getInstance();
-				let vss = [{ key: "/topic/voice-control", action: this.windturbineMessage }];
-				let attention = [{ key: "/topic/attention", action: this.attention }];
-				mb.register(attention);
-				mb.register(vss);
-			},
-			attention(msg) {
-				let list = JSON.parse(msg)
-				let types = {
-					ElectricityRestrictions: '限电',
-					Offline: '离线',
-					Accident: '故障',
-				}
-				list.forEach(item => {
-					item.createTime = dayjs(item.time).format('YYYY-MM-DD HH:mm:ss')
-					item.showType = types[item.type]
-				})
-				this.values = list
-			},
-			windturbineMessage(msg) {
-				let bd = BackgroundData.getInstance();
-				let arr = []
-				if (msg === 'CLOSE') {
-					arr.push(msg)
-				} else {
-					arr = msg.split('-')
-				}
-				this.dialogVisible = false
-				this.svgWeb = ''
-				if (arr[0] === 'OPEN_AGC' && arr[1] !== 'GS') {
-					let data = bd.Recommends
-					for (let v in data) {
-						if (arr[1] === data[v].stationID) {
-							this.sendMsg(data[v])
-						}
-					}
-				} else if (arr[0] === 'CLOSE') {
-					this.dialogVisible = false
-					this.svgVisible = false
-				}
-			},
-			closed() {
-				clearInterval(this.interval);
-			},
-			close() {
-				this.svgVisible = false;
-			},
-			initData() {
-				setInterval(this.refreshData, 2000);
-			},
-			refreshData() {
-				let bd = BackgroundData.getInstance();
-				let list = new Array();
-				let thisKey = ''
-				for (let v in bd.Recommends) {
-					thisKey += v + ',';
-				}
-				axios.get(process.env.VUE_APP_ADAPTERURL + `/ts/latest?keys=` + thisKey)
-					.then(msg => {
-						for (let v in msg.data) {
-							if (msg.data[v].doubleValue ? (msg.data[v].doubleValue > 0) : (msg.data[v].booleanValue)) {
-								bd.Recommends[v].isActive = true
-							}
-						}
-						for (let rec in bd.Recommends) {
-							if (bd.Recommends[rec].isActive) {
-								list.push(bd.Recommends[rec])
-							}
-						}
-						list.forEach(item => {
-							item.createTime = dayjs(item.createTime).format('YYYY-MM-DD HH:mm:ss')
-						})
-						this.values = list
-					})
-			},
-			sendMsg: function (vl, index) {
-				if (vl.attentionType === 'Station' && vl.type === 'Accident') {
-					this.svgVisible = true;
-					this.svgWeb = vl.stationId;
-					this.stationNames = vl.name
-				} else if (vl.attentionType === 'Station' && vl.type === 'ElectricityRestrictions') {
-					let that = this;
-					that.timeIndex = 0;
-					that.ajaxDetail(vl, index);
-					that.interval = window.setInterval(function () {
-						that.ajaxDetail(vl, index);
-					}, 3000);
-					that.dialogVisible = true;
-					that.dialogData.stationName = vl.name;
-				} else if (vl.attentionType === 'WindTurbine') {
-					this.windVisible = true;
-					this.currentWindturbine = this.$store.state.windturbinelist[vl.id];
-				}
+import PhotoelectricDetailPages from "./PhotoelectricDetailPages.vue";
+import MessageBridge from "utils/MessageBridge";
+import StationSvgDetailPages from "../stationSvgDetailPages.vue";
+import WindturbineDetailPages from "../WindturbineDetailPages.vue";
+import api from "api/index";
+import dayjs from "dayjs";
+export default {
+  name: "RecommendedArea",
+  props: ["datas"],
+  data() {
+    return {
+      values: [],
+      currentWindturbine: {},
+      dialogVisible: false,
+      svgVisible: false,
+      windVisible: false,
+      svgWeb: "",
+      station: [],
+      dialogData: {
+        data: {
+          PowerSet: "",
+          AgcUp: "",
+          AgcLower: "",
+          ActualPower: "",
+          TheoryPower: "",
+          ForecastPower: "",
+          AgcIn: "",
+          AgcFar: "",
+          SumLock: "",
+          SubLock: "",
+        },
+      },
+      interval: "",
+      intervalTimer: "",
+      timeIndex: 0,
+    };
+  },
+  components: {
+    PhotoelectricDetailPages,
+    StationSvgDetailPages,
+    WindturbineDetailPages,
+  },
+  created() {
+    this.datacontrol();
+    this.getAGCStation();
+  },
+  methods: {
+    getAGCStation() {
+      api.getAGCStation().then((res) => {
+        this.station = res.data;
+      });
+    },
+    datacontrol() {
+      let mb = MessageBridge.getInstance();
+      let attention = [{ key: "/topic/attention", action: this.attention }];
+      mb.register(attention);
+    },
+    attention(msg) {
+      let list = JSON.parse(msg);
+      let types = {
+        ElectricityRestrictions: "限电",
+        Offline: "离线",
+        Accident: "故障",
+        LowCurveFollowingRate: "跟随率低",
+      };
+      list.forEach((item) => {
+        item.createTime = dayjs(item.time).format("YYYY-MM-DD HH:mm:ss");
+        item.showType = types[item.type];
+      });
+      this.values = list;
+    },
+    closed() {
+      clearInterval(this.intervalTimer);
+      this.intervalTimer = null
+    },
+    close() {
+      this.svgVisible = false;
+    },
 
-			},
-			ajaxDetail(data, index) {
-				let thisKey = Photoelectric[data.id];
-				let array = []
-				thisKey.forEach(item => { item.value ? array.push(item.value) : '' })
-				let params = array.join(',')
-				api.getLatest(params).then(res => {
-					if (res) {
-						console.log(res, this.dialogData.data, thisKey);
-						for (let v in res.data) {
-							thisKey.forEach(item => {
-								let calc = item.calc ? item.calc : 1;
-								if (item.value === v) {
-									this.dialogData.data[item.tag] = {
-										name: item.name,
-										value: res.data[v].doubleValue ? res.data[v].doubleValue === 0 ? '0' : (res.data[v].doubleValue * calc).toFixed(2) : (res.data[v].booleanValue ? 1 : 0)
-									}
-									console.log(this.dialogData.data);
-								}
-							})
-						}
-					}
-				})
-				if (this.timeIndex == 0) {//一分钟执行一次
-					let date = new Date()
-					let endTs = date.getTime();
-					let starTs = endTs - 28800000;
-					const PowerSet = thisKey.find(ele => {
-						return ele.tag == 'PowerSet'
-					});
-					const ActualPower = thisKey.find(ele => {
-						return ele.tag == 'ActualPower'
-					});
-					let PowerSetData = [],
-						ActualPowerData = [];
-					api.getPower({
-						tagName: PowerSet.value,
-						startTs: starTs,
-						endTs: endTs,
-						interval: 60,
-					}).then(res1 => {
-						api.getPower({
-							tagName: ActualPower.value,
-							startTs: starTs,
-							endTs: endTs,
-							interval: 60,
-						}).then(res2 => {
-							res1.data.forEach(item => {
-								PowerSetData.push({
-									ts: item.ts,
-									doubleValue: item.doubleValue * PowerSet.calc
-								})
-							})
-							res2.data.forEach(item => {
-								ActualPowerData.push({
-									ts: item.ts,
-									doubleValue: item.doubleValue * ActualPower.calc
-								})
-							})
-							this.$refs.photo.initData(PowerSetData, ActualPowerData);
-						});
-					});
-				} else if (this.timeIndex == 20) {
-					this.timeIndex = -1;
-				}
-				this.timeIndex++;
-			},
-		},
-	};
+    sendMsg: function (vl, types, index) {
+      if (vl.attentionType === "Station" && vl.type === "Accident") {
+        // this.svgVisible = true;
+        // this.svgWeb = vl.stationId;
+      } else if (
+        (vl.attentionType === "Station" &&
+          vl.type === "ElectricityRestrictions") ||
+        types
+      ) {
+        let that = this;
+        that.timeIndex = 0;
+        that.ajaxDetail(vl, index);
+        that.intervalTimer = window.setInterval(function () {
+          that.ajaxDetail(vl, index);
+        }, 3000);
+        that.dialogVisible = true;
+        that.dialogData.stationName = this.station.filter(
+          (item) => item.id === vl.id
+        )[0].name;
+      } else if (vl.attentionType === "WindTurbine") {
+        this.windVisible = true;
+        this.currentWindturbine = this.$store.state.windturbinelist[vl.id];
+      }
+    },
+    ajaxDetail(data, index) {
+      let thisKey = this.station.filter((item) => item.id === data.id)[0].tags;
+      let array = [];
+      thisKey.forEach((item) => {
+        item.value ? array.push(item.value) : "";
+      });
+      let params = array.join(",");
+      api.getLatest(params).then((res) => {
+        if (res) {
+          for (let v in res.data) {
+            thisKey.forEach((item) => {
+              let calc = item.calc ? item.calc : 1;
+              if (item.value === v) {
+                this.dialogData.data[item.tag] = {
+                  name: item.name,
+                  value: res.data[v].doubleValue
+                    ? res.data[v].doubleValue === 0? 0 : Number((res.data[v].doubleValue * calc).toFixed(2))
+                    : res.data[v].booleanValue? 1: 0,
+                };
+              }
+            });
+          }
+        }
+      });
+      if (this.timeIndex == 0) {
+        //一分钟执行一次
+        let date = new Date();
+        let endTs = date.getTime();
+        let starTs = endTs - 28800000;
+        const PowerSet = thisKey.find((ele) => {
+          return ele.tag == "PowerSet";
+        });
+        const ActualPower = thisKey.find((ele) => {
+          return ele.tag == "ActualPower";
+        });
+        let PowerSetData = [],
+          ActualPowerData = [];
+        api
+          .getPower({
+            tagName: PowerSet.value,
+            startTs: starTs,
+            endTs: endTs,
+            interval: 60,
+          })
+          .then((res1) => {
+            api
+              .getPower({
+                tagName: ActualPower.value,
+                startTs: starTs,
+                endTs: endTs,
+                interval: 60,
+              })
+              .then((res2) => {
+                res1.data.forEach((item) => {
+                  PowerSetData.push({
+                    ts: item.ts,
+                    doubleValue: item.doubleValue * PowerSet.calc,
+                  });
+                });
+                res2.data.forEach((item) => {
+                  ActualPowerData.push({
+                    ts: item.ts,
+                    doubleValue: item.doubleValue * ActualPower.calc,
+                  });
+                });
+                this.$refs.photo.initData(PowerSetData, ActualPowerData);
+              });
+          });
+      } else if (this.timeIndex == 20) {
+        this.timeIndex = -1;
+      }
+      this.timeIndex++;
+    },
+  },
+};
 </script>
 <style scoped>
-	/* table {
-		background-image: url("../../assets/img/RecommendedArea/background.png");
-		text-align: center;
-		font-size: 12px;
-		background-size: 110px;
-		margin-left: 10px;
-		margin-top: 10px;
-		padding-top: 10px;
-		background-repeat: no-repeat;
-		color: #ffffff;
-	} */
-	.imgs {
-		/* width: 70px;
-		height: 66px; */
-	}
+.area {
+  display: flex;
+  flex-direction: column;
+  font-size: 12px;
+  color: #ffffff;
+  width: 130px;
+  align-items: center;
+  margin-bottom: 10px;
+}
 
-	.area {
-		display: flex;
-		flex-direction: column;
-		font-size: 12px;
-		color: #ffffff;
-		width: 130px;
-		align-items: center;
-		margin-bottom: 10px;
-	}
-
-	.content {
-		margin-top: -70px;
-		width: 25px;
-		height: 34px;
-		margin-bottom: 20px;
-		display: flex;
-		align-items: center;
-	}
-</style>
+.content {
+  margin-top: -70px;
+  width: 25px;
+  height: 34px;
+  margin-bottom: 20px;
+  display: flex;
+  align-items: center;
+}
+</style>

+ 89 - 84
src/components/focus/multiple-line-chart.vue

@@ -1,96 +1,100 @@
 <template>
-  <div class="chart" id="showEchart"></div>
+  <div class="charts" id="showEchart"></div>
 </template>
 
 <script>
-  import * as echarts from "echarts";
-  export default {
-    name: "multiple-line-chart",
-    componentName: "multiple-line-chart",
-    data() {
-      return {
-        id: "",
-        chart: null,
-      };
-    },
-    methods: {
-      initChart(chartData) {
-        let chartDom = document.getElementById('showEchart');
-        let myChart = echarts.init(chartDom, '#ffffff');
-        let option = {
-          legend: {
-            show: true,
-            data: chartData.value.map((t) => {
-              return t.title;
-            }),
-            right: 56,
-            icon: "circle",
-            itemWidth: 6,
-            inactiveColor: '#606769',
-            textStyle: {
-              color: '#B3BDC0',
-              fontSize: 12,
-            },
+import * as echarts from "echarts";
+export default {
+  name: "multiple-line-chart",
+  componentName: "multiple-line-chart",
+  data() {
+    return {
+      id: "",
+      chart: null,
+    };
+  },
+  methods: {
+    initChart(chartData) {
+      let chartDom = document.getElementById("showEchart");
+      let myChart = echarts.init(chartDom, "#ffffff");
+      let option = {
+        tooltip: {
+          trigger: 'axis'
+        },
+        legend: {
+          show: true,
+          data: chartData.value.map((t) => {
+            return t.title;
+          }),
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: "#606769",
+          textStyle: {
+            color: "#B3BDC0",
+            fontSize: 12,
           },
+        },
 
-          xAxis: [
-            {
-              type: "category",
-              boundaryGap: false,
-              axisLabel: {
-                // interval: 60,
-                showMinLabel: true,
-                showMaxLabel: true,
-                formatter: "{value}",
-                fontSize: 14,
-                textStyle: {
-                  color: '#606769',
-                },
-              },
-              axisLine: {
-                show: false,
-              },
-              data: chartData.value[0].value.map(items => {
-                return items.text;
-              }),
-            },
-          ],
-          yAxis: {
-            type: "value",
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
             axisLabel: {
+              // interval: 60,
+              showMinLabel: true,
+              showMaxLabel: true,
               formatter: "{value}",
               fontSize: 14,
+              textStyle: {
+                color: "#606769",
+              },
             },
             axisLine: {
               show: false,
             },
-            splitLine: {
-              show: true,
-              lineStyle: {
-                color: '#606769',
-                type: "dashed",
-              },
-            },
+            data: chartData.value[0].value.map((items) => {
+              return items.text;
+            }),
           },
-          dataZoom: [
-            {
-              show: false,
-              type: 'inside',
-              start: 0,
-              end: 100
+        ],
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: 14,
+          },
+          axisLine: {
+            show: false,
+          },
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "#606769",
+              type: "dashed",
             },
-          ],
-          series: [{
+          },
+        },
+        dataZoom: [
+          {
+            show: false,
+            type: "inside",
+            start: 0,
+            end: 100,
+          },
+        ],
+        series: [
+          {
             name: chartData.value[0].title,
             smooth: true,
             showSymbol: false,
-            data: chartData.value[0].value.map(items => {
+            data: chartData.value[0].value.map((items) => {
               return items.value;
             }),
-            type: 'line',
+            type: "line",
             lineStyle: {
               normal: {
-                color: 'rgba(75, 85, 174, 1)',
+                color: "rgba(75, 85, 174, 1)",
                 width: 1,
               },
             },
@@ -99,27 +103,28 @@
             name: chartData.value[1].title,
             smooth: true,
             showSymbol: false,
-            data: chartData.value[1].value.map(items => {
+            data: chartData.value[1].value.map((items) => {
               return items.value;
             }),
-            type: 'line',
+            type: "line",
             lineStyle: {
               normal: {
-                color: 'rgba(05, 187, 76, 1)',
+                color: "rgba(05, 187, 76, 1)",
                 width: 1,
               },
             },
-          }]
-        };
-        option && myChart.setOption(option);
-      },
+          },
+        ],
+      };
+      option && myChart.setOption(option);
     },
-  };
+  },
+};
 </script>
 
-<style lang="less">
-  .chart {
-    width: 1050px;
-    height: 40vh;
-  }
+<style lang="less" scoped>
+.charts {
+  width: 1050px;
+  height: 40vh;
+}
 </style>

+ 691 - 231
src/components/focus/syzDetails.vue

@@ -13,65 +13,84 @@
       </div>
     </template>
     <div class="bodyy">
-      <el-tabs
-        type="border-card"
-        stretch
-        lazy
-        style="width: 100%; height: 100%"
-        v-model="activeTab"
-        @tab-click="tabClick"
-      >
-        <el-tab-pane
-          class="syzDetailsPaneItem"
-          v-for="(item, index) in syzArray"
-          :key="index"
-          :name="item.id"
+        <el-tabs
+            type="border-card"
+            stretch
+            lazy
+            style="width: 100%; height: 100%"
+            v-model="activeTab"
+            @tab-click="tabClick"
         >
-          <template #label>
-            <span v-if="pageshowMode % 2">
-              <el-badge is-dot v-if="item.isWarning === '1'">
-                <span>{{ item.name }}</span>
-              </el-badge>
-              <span v-else>{{ item.name }}</span>
-            </span>
-            <span v-else>
-              <el-badge is-dot v-if="item.isWarning === '1'">
-                <span>{{ item.name }}</span>
-              </el-badge>
-              <span v-else>{{ item.name }}</span>
-            </span>
-          </template>
-          <Mhs v-if="item.id === 'MHS_FDC'" />
-          <Nss v-if="item.id === 'NSS_FDC'" />
-          <Qs v-if="item.id === 'QS_FDC'" />
-          <Sbq v-if="item.id === 'SBQ_FDC'" />
-          <Xs v-if="item.id === 'XS_FDC'" />
-          <Pl1 v-if="item.id === 'PL1_GDC'" />
-          <Pl2 v-if="item.id === 'PL2_GDC'" />
-          <Dwk v-if="item.id === 'DWK_GDC'" />
-          <Mch v-if="item.id === 'MCH_GDC'" />
-          <Xh v-if="item.id === 'XH_GDC'" />
-          <Sbdl v-if="item.id === 'QS3_FDC'" />
-          <div class="alarmIconBox" @click="switchAlarmSound(index)">
-            <el-tooltip
-              v-if="item.isMute"
-              effect="light"
-              :content="`当前${item.name}升压站报警已消音,请注意`"
-              placement="left"
+            <el-tab-pane
+            class="syzDetailsPaneItem"
+            v-for="(item, index) in syzArray"
+            :key="index"
+            :name="item.id"
             >
-              <i
-                class="el-icon-close-notification"
-                style="color: orangered"
-              ></i>
-            </el-tooltip>
-            <i v-else class="el-icon-bell" style="color: rgb(219, 215, 0)"></i>
-          </div>
-        </el-tab-pane>
-      </el-tabs>
-      <CurrentWarningCard
-        :currentClass="$store.state.currentWarningCardClass"
-        :activeTab="activeTab || 'MHS_FDC'"
-      />
+            <template #label>
+                <span v-if="pageshowMode % 2">
+                <el-badge is-dot v-if="item.isWarning === '1'">
+                    <span>{{ item.name }}</span>
+                </el-badge>
+                <span v-else>{{ item.name }}</span>
+                </span>
+                <span v-else>
+                <el-badge is-dot v-if="item.isWarning === '1'">
+                    <span>{{ item.name }}</span>
+                </el-badge>
+                <span v-else>{{ item.name }}</span>
+                </span>
+            </template>
+            <div class="buttonGroup" v-if="item.id === 'all'" >
+                <el-button-group>
+                    <el-button type="plain" size="small" @click="changeHeight('D')" :class="allHeight === 'D' ? 'showSty' : ''">大图标</el-button>
+                    <el-button type="plain" size="small" @click="changeHeight('Z')" :class="allHeight === 'Z' ? 'showSty' : ''">中图标</el-button>
+                    <el-button type="plain" size="small" @click="changeHeight('X')" :class="allHeight === 'X' ? 'showSty' : ''">小图标</el-button>
+                </el-button-group>
+            </div>
+            <div v-if="item.id === 'all'" :style="allpageHeight" style="width: 100%;display: inline-block;overflow-y:auto">
+                <div v-for="(item, index) in allSvgMsgData" :key="index" :style="getStyle(allHeight)">
+                    <div class="showAllSvgMsg" @dblclick="dblgetSvgDataFn(item.id)" :class="getWarnstyle(item)">
+                        <div class="showAllSvgMsg_top" v-html="item.msg"></div>
+                        <div class="showAllSvgMsg_bot">
+                            <span>{{item.name}}</span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div id="svg" :style="pageHeight" v-if="item.id !== 'all' && item.id === activeTab" v-html="svgMsg" v-loading="loading"></div>
+            <!-- <Mhs ref="svgRef" v-if="item.id === 'MHS_BT'" />
+            <Nss ref="svgRef" v-if="item.id === 'NSS_FDC'" />
+            <Qs ref="svgRef" v-if="item.id === 'QS_FDC'" />
+            <Sbq ref="svgRef" v-if="item.id === 'SBQ_FDC'" />
+            <Xs ref="svgRef" v-if="item.id === 'XS_FDC'" /> -->
+            <!-- <Pl1 ref="svgRef" v-if="item.id === 'PL1_GDC'" />
+            <Pl2 ref="svgRef" v-if="item.id === 'PL2_GDC'" />
+            <Dwk ref="svgRef" v-if="item.id === 'DWK_GDC'" />
+            <Mch ref="svgRef" v-if="item.id === 'MCH_GDC'" />
+            <Xh ref="svgRef" v-if="item.id === 'XH_GDC'" />
+            <Sbdl ref="svgRef" v-if="item.id === 'QS3_FDC'" /> -->
+            <div class="alarmIconBox" v-if="item.id !== 'all'" @click="switchAlarmSound(index)">
+                <el-tooltip
+                v-if="item.isMute"
+                effect="light"
+                :content="`当前${item.name}升压站报警已消音,请注意`"
+                placement="left"
+                >
+                <i
+                    class="el-icon-close-notification"
+                    style="color: orangered"
+                ></i>
+                </el-tooltip>
+                <i v-else class="el-icon-bell" style="color: rgb(219, 215, 0)"></i>
+            </div>
+            </el-tab-pane>
+        </el-tabs>
+        <CurrentWarningCard
+            :currentClass="$store.state.currentWarningCardClass"
+            :activeTab="activeTab || 'MHS_FDC'"
+            v-if="activeTab !== 'all'"
+        />
     </div>
   </el-dialog>
 </template>
@@ -88,199 +107,560 @@ import Pl2 from "../BoosterStation/pl2.vue";
 import Mch from "../BoosterStation/mch.vue";
 import Xh from "../BoosterStation/xh.vue";
 
+import api from "api/index";
+
 import CurrentWarningCard from "./currentWarningCard.vue";
 export default {
-  components: {
-    Mhs,
-    Nss,
-    Qs,
-    Sbq,
-    Xs,
-    Dwk,
-    Sbdl,
-    Pl1,
-    Pl2,
-    Mch,
-    Xh,
-    CurrentWarningCard,
-  },
-  data() {
-    return {
-      activeTab: this.$store.state.activeTab,
-      svgVisible: true,
-      audio: null,
-      timmer: null,
-      syzArray: this.$store.getters.syzArray || [],
-      pageshowMode: 0,
-    };
-  },
-  created() {},
-  mounted() {},
-  updated() {},
-  methods: {
-    // 初始化第一次报警并判断是否播放声音
-    initAlarm() {
-      let syzAlarmArray = this.$store.getters.syzAlarmArray;
-
-      const firstAlarmItem = syzAlarmArray.find((ele) => {
-        return !ele.isConfirm && ele.rank === this.$store.state.syzAlarmRank;
-      });
-
-      firstAlarmItem &&
-        this.audioPlay(this.getSound(firstAlarmItem.soundSource));
-
-      firstAlarmItem &&
-        this.$store.getters.syzAlarmArray.forEach((ele) => {
-          if (ele.stationId === firstAlarmItem.stationId) {
-            ele.isConfirm = true;
-          }
+    props: {
+        activeTabStation: {
+        type: String,
+        default: "",
+        },
+    },
+    components: {
+        Mhs,
+        Nss,
+        Qs,
+        Sbq,
+        Xs,
+        Dwk,
+        Sbdl,
+        Pl1,
+        Pl2,
+        Mch,
+        Xh,
+        CurrentWarningCard
+    },
+    data() {
+        return {
+            activeTab: this.$store.state.activeTab,
+            svgVisible: true,
+            audio: null,
+            timmer: null,
+            syzArray: [],
+            pageshowMode: 0,
+            svgMsg: '',
+            loading: false,
+            allTagidArr: [],
+            starTimer: null,
+            allTagsMS: {},
+            allrefreshData: {},
+            allConditions: {},
+            onlytag: {},
+            allSvgMsgData: [],
+            allHeight: 'D',
+            allWarnData: [],
+            starTimerWarn: null,
+            numm: 0,
+            stationSort: []
+        };
+    },
+    computed: {
+        pageHeight() {
+            return {
+                'height': document.documentElement.clientHeight-60 + 'px'
+            }
+        },
+        allpageHeight() {
+            return {
+                'height': document.documentElement.clientHeight-200 + 'px'
+            }
+        },
+    },
+    mounted() {
+    },
+    updated() {},
+    methods: {
+        // 获取升压站报警数据
+        getSyzWarnData() {
+            api.alarmFault().then((res) => {
+                if (res && res.data) {
+                    let datas = res.data
+                    let arr = []
+                    datas.forEach(it =>{
+                        if (it.rank === '5' && it.category1 === 'SYZ') {
+                            // if (it.stationName.indexOf('风电场') !== -1 ) {
+                            //     str = it.stationName.substring(0, it.stationName.indexOf('风电场'))
+                            // } else if (it.stationName.indexOf('光伏电站') !== -1) {
+                            //     str = it.stationName.substring(0, it.stationName.indexOf('光伏电站'))
+                            // }
+                            arr.push(it.category2)
+                        }
+                        // let str = ''
+                    })
+                    this.allWarnData = this.unique(arr)
+                }
+            })
+        },
+        unique(arr) {
+            let newArr = []
+            for(let i=0; i<arr.length; i++) {
+                if (newArr.indexOf(arr[i]) === -1) {
+                    newArr.push(arr[i])
+                }
+            }
+            return newArr
+        },
+        getWarnstyle(item) {
+            let showWarn = ''
+            this.allWarnData.forEach(it=> {
+                if (it === item.id) {
+                    showWarn = 'warningMaskNew'
+                }
+            })
+            return showWarn
+        },
+        getStyle(type) {
+            let num = null
+            let num1 = null
+            let num2 = null
+            if (type === 'D') {
+                return {
+                    'width': '33.3%',
+                    'float': 'left',
+                    'height': '400px'
+                }
+            } else if (type === 'Z') {
+                num = parseInt(this.allSvgMsgData.length / 4)
+                num1 = this.allSvgMsgData.length % 4
+                num2 = num1 > 0 ? num + 1 : num
+                return {
+                    'width': '25%',
+                    'float': 'left',
+                    'height': (document.documentElement.clientHeight-200) / num2 + 'px'
+                }
+            } else {
+                num = parseInt(this.allSvgMsgData.length / 5)
+                num1 = this.allSvgMsgData.length % 5
+                num2 = num1 > 0 ? num + 1 : num
+                return {
+                    'width': '20%',
+                    'float': 'left',
+                    'height': (document.documentElement.clientHeight-200) / num2 + 'px'
+                }
+            }
+            
+        },
+        changeHeight(type) {
+            this.allHeight = type
+        },
+        getAllStationtab() {
+            let obj = {
+                id: 'all',
+                name: '全部'
+            }
+            api.getAllStationTab().then((res) => {
+                if (res && res.data) {
+                    res.data.unshift(obj)
+                    this.syzArray = res.data
+                    this.activeTab = res.data[0].id
+                    if (this.activeTab === 'all') {
+                        let allMsg = res.data
+                        this.allSvgMsgData = []
+                        this.stationSort = []
+                        allMsg.forEach(it =>{
+                            if (it.id !== 'all') {
+                                this.stationSort.push(it.name)
+                                this.getallSvgDataFn(it.id, it.name)
+                            }
+                        })
+                        // window.sessionStorage.setItem('allSvgData', [])
+                        console.log('allSvgMsgData', this.allSvgMsgData)
+                        console.log('stationSort', this.stationSort)
+                        console.log('allMsg', allMsg)
+                    }
+                    
+                    // this.getSvgDataFn(res.data[0].id)
+                }
+            })
+        },
+        // 获取所有升压站数据
+        getallSvgDataFn(id, name) {
+            let params = {
+                id: id
+            }
+            api.getSvgData(params).then((res) => {
+                let str = ''
+                str = res.data.substring(res.data.indexOf('<svg'))
+                str = str.replace('<svg', '<svg viewBox="0 -100 1900 1260"')
+                let obj = {
+                    id: id,
+                    name: name,
+                    msg: str
+                }
+                this.allSvgMsgData.push(obj)
+                if (this.allSvgMsgData.length === this.stationSort.length) {
+                    let sortArr = []
+                    this.stationSort.forEach(itc =>{
+                        this.allSvgMsgData.forEach(itb =>{
+                            if (itc === itb.name) {
+                                sortArr.push(itb)
+                            }
+                        })
+                    })
+                    this.allSvgMsgData = sortArr
+                }
+            })
+        },
+        // 获取升压站数据
+        getSvgDataFn(val) {
+            this.svgMsg = ''
+            this.loading = true
+            let params = {
+                id: val
+            }
+            api.getSvgData(params).then((res) => {
+                if (res && res.data) {
+                    let str = ''
+                    str = res.data.substring(res.data.indexOf('<svg'))
+                    str = str.replace('<svg', '<svg viewBox="0 0 1900 1260"')
+                    this.svgMsg = str
+                    let html = document.getElementById('svg')
+                    let svg1 = document.getElementsByTagName('svg')
+                    this.$nextTick(() =>{
+                        if (svg1) {
+                            let allTags = []
+                            let allTagsxc = []
+                            let status = ['g', 'text', 'rect', 'line', 'polyline', 'circle', 'ellipse', 'polygon']
+                            status.forEach(it =>{
+                                let allgs = []
+                                allgs = document.querySelectorAll(it);
+                                allTags.push(allgs)
+                            })
+                            allTags = [...allTags[0], ...allTags[1], ...allTags[2], ...allTags[3], ...allTags[4], ...allTags[5], ...allTags[6], ...allTags[7]]
+                            allTags.forEach((it) => {
+                                if (it.getAttribute("tagid")) {
+                                    allTagsxc.push(it);
+                                }
+                            });
+                            console.log('allTags222=>', allTagsxc)
+                            this.allTagidArr = allTagsxc
+                            this.getSvgInfo()
+                        }
+                        console.log('html111=>', html)
+                    })
+                    this.loading = false
+                }
+            })
+        },
+        // 获取触发器
+        getSvgInfo() {
+            let params = {
+                id: this.activeTab
+            }
+            api.getAllStationSvgInfo(params).then((res) => {
+                if (res && res.data) {
+                    if (res.data.tags) {
+                        let strarr = []
+                        let str = ''
+                        for(let i in res.data.tags) {
+                            strarr.push(res.data.tags[i].tag)
+                        }
+                        str = strarr.join(',')
+                        this.allTagsMS = res.data.tags
+                        this.allConditions = res.data.conditions
+                        // this.getrefreshData(str)
+                        this.starTimer = setInterval(() =>{
+                            this.getrefreshData(str)
+                        }, 1000)
+                    }
+                    console.log('SvgInfo333=>', res)
+                }
+            })
+        },
+        // 获取根盾数据
+        getrefreshData(val) {
+            api.refreshData(val).then((res) => {
+                if (res && res.data) {
+                    this.allrefreshData = res.data
+                    this.refreshDataFn(this.allTagsMS)
+                }
+                console.log('refreshData444=>', res)
+            })
+        },
+        // 刷新数据
+        refreshDataFn(datas) {
+            for (let it in datas) {
+                let tagId = datas[it];
+                this.toRefreshFn(it, tagId);
+            }
+        },
+        // 刷新自定义组件
+        toRefreshFn(val, data) {
+            var tag = this.allrefreshData[data.tag];
+            if (!tag) return;
+            this.allTagidArr.forEach(it =>{
+                this.onlytag = {}
+                if (it.attributes.tagid) {
+                    if (val === it.attributes.tagid.value) {
+                        this.onlytag = it
+                        if (it.nodeName === 'polyline') {
+                            console.log('onlyTag666', this.onlytag)
+                        }
+                        if (it.nodeName !== 'text') {
+                            if (this.onlytag.attributes.csid) {
+                                let csid = this.onlytag.attributes.csid.value.split(';')
+                                csid.forEach(ic =>{
+                                    if (ic) {
+                                        if (!this.allConditions[ic].isBinding) {
+                                            let num = parseInt(this.allConditions[ic].value) === 0 ? '0' : parseInt(this.allConditions[ic].value)
+                                            if (num) {
+                                                let num2 = tag.value === 0 ? '0' : tag.value
+                                                if (num === num2) {
+                                                    this.onlytag.setAttribute(this.allConditions[ic].property, this.allConditions[ic].propertyValue)
+                                                    return 
+                                                }
+                                            }
+                                        } else {
+                                            this.onlytag.setAttribute(this.allConditions[ic].property, this.allConditions[ic].propertyValue)
+                                        }
+                                    }
+                                })
+                            }
+                        } else {
+                            this.onlytag.textContent = tag.value.toFixed(2)
+                        }
+                    }
+                }
+            })
+            // console.log('onlyTag555', this.onlytag)
+        },
+        // '全部'界面双击事件
+        dblgetSvgDataFn(name) {
+            this.activeTab = name
+            this.getSvgDataFn(name)
+        },
+        // 初始化第一次报警并判断是否播放声音
+        initAlarm() {
+        let syzAlarmArray = this.$store.getters.syzAlarmArray;
+
+        const firstAlarmItem = syzAlarmArray.find((ele) => {
+            return !ele.isConfirm && ele.rank === this.$store.state.syzAlarmRank;
         });
 
-      this.activeTab =
-        firstAlarmItem?.stationId ||
-        syzAlarmArray.find((ele) => {
-          return ele.rank === this.$store.state.syzAlarmRank;
-        })?.stationId ||
-        this.$store.getters.syzArray[0].id;
-
-      syzAlarmArray.forEach((ele) => {
-        if (ele.stationId === firstAlarmItem?.stationId) {
-          ele.isConfirm = true;
-          this.clearWarningTag(ele.stationId);
-        } else if (
-          !ele.isConfirm &&
-          ele.stationId !== firstAlarmItem?.stationId
-        ) {
-          this.renderWarningTag(ele.stationId);
-        }
-      });
+        firstAlarmItem &&
+            this.audioPlay(this.getSound(firstAlarmItem.soundSource));
 
-      this.$store.commit("syzAlarmArray", syzAlarmArray);
-    },
+        firstAlarmItem &&
+            this.$store.getters.syzAlarmArray.forEach((ele) => {
+            if (ele.stationId === firstAlarmItem.stationId) {
+                ele.isConfirm = true;
+            }
+            });
+
+        this.activeTab = 
+            this.activeTabStation ||
+            firstAlarmItem?.stationId ||
+            syzAlarmArray.find((ele) => {
+            return ele.rank === this.$store.state.syzAlarmRank;
+            })?.stationId ||
+            this.$store.getters.syzArray[0].id;
+
+        syzAlarmArray.forEach((ele) => {
+            if (ele.stationId === firstAlarmItem?.stationId) {
+            ele.isConfirm = true;
+            this.clearWarningTag(ele.stationId);
+            } else if (
+            !ele.isConfirm &&
+            ele.stationId !== firstAlarmItem?.stationId
+            ) {
+            this.renderWarningTag(ele.stationId);
+            }
+        });
 
-    // 定时器循环数据判断小红点渲染及是否播放声音
-    renderAlarm(stationId = "", playSound = true) {
-      let syzAlarmArray = this.$store.getters.syzAlarmArray;
+        this.$store.commit("syzAlarmArray", syzAlarmArray);
+        },
 
-      syzAlarmArray.forEach((ele) => {
-        if (ele.stationId === stationId) {
-          ele.isConfirm = true;
-          this.clearWarningTag(ele.stationId);
-        } else if (!ele.isConfirm && ele.stationId !== stationId) {
-          this.renderWarningTag(ele.stationId);
-        }
-      });
+        // 定时器循环数据判断小红点渲染及是否播放声音
+        renderAlarm(stationId = "", playSound = true) {
+        let syzAlarmArray = this.$store.getters.syzAlarmArray;
 
-      const res = syzAlarmArray.find((ele) => {
-        return !ele.isConfirm;
-      });
+        syzAlarmArray.forEach((ele) => {
+            if (ele.stationId === stationId) {
+            ele.isConfirm = true;
+            this.clearWarningTag(ele.stationId);
+            } else if (!ele.isConfirm && ele.stationId !== stationId) {
+            this.renderWarningTag(ele.stationId);
+            }
+        });
 
-      if (playSound) {
-        // this.audioPlay("./static/sound/syz.mp3");
-      }
+        const res = syzAlarmArray.find((ele) => {
+            return !ele.isConfirm;
+        });
 
-      this.$store.commit("syzAlarmArray", syzAlarmArray);
-    },
+        if (playSound) {
+            // this.audioPlay("./static/sound/syz.mp3");
+        }
 
-    // 返回音频文件路径
-    getSound(fileName) {
-      return `./static/sound/${fileName}.mp3`;
-    },
+        this.$store.commit("syzAlarmArray", syzAlarmArray);
+        },
 
-    // 播放音频
-    audioPlay(audioPath) {
-      let soundMuteSelf = [];
-      let soundMuteOther = [];
+        // 返回音频文件路径
+        getSound(fileName) {
+        return `./static/sound/${fileName}.mp3`;
+        },
 
-      this.$store.getters.syzAlarmArray.forEach((ele) => {
-        if (ele.stationId === this.activeTab) {
-          soundMuteSelf.push(ele);
-        } else {
-          soundMuteOther.push(ele);
-        }
-      });
+        // 播放音频
+        audioPlay(audioPath) {
+        let soundMuteSelf = [];
+        let soundMuteOther = [];
 
-      let alarmSelfLock = soundMuteSelf.some((ele) => {
-        return !ele.isConfirm;
-      });
+        this.$store.getters.syzAlarmArray.forEach((ele) => {
+            if (ele.stationId === this.activeTab) {
+            soundMuteSelf.push(ele);
+            } else {
+            soundMuteOther.push(ele);
+            }
+        });
 
-      let alarmOtherLock = soundMuteOther.some((ele) => {
-        return !ele.isConfirm;
-      });
+        let alarmSelfLock = soundMuteSelf.some((ele) => {
+            return !ele.isConfirm;
+        });
 
-      if (alarmOtherLock) {
-        this.audio = new Audio(audioPath);
-        this.audio.play();
-      } else if (alarmSelfLock) {
-        this.$store.getters.syzArray.forEach((ele) => {
-          if (ele.stationId === this.activeTab) {
-            ele.isMute = false;
+        let alarmOtherLock = soundMuteOther.some((ele) => {
+            return !ele.isConfirm;
+        });
+
+        if (alarmOtherLock) {
             this.audio = new Audio(audioPath);
             this.audio.play();
-          }
-        });
-      } else if (!alarmSelfLock) {
+        } else if (alarmSelfLock) {
+            this.$store.getters.syzArray.forEach((ele) => {
+            if (ele.stationId === this.activeTab) {
+                ele.isMute = false;
+                this.audio = new Audio(audioPath);
+                this.audio.play();
+            }
+            });
+        } else if (!alarmSelfLock) {
+            this.$store.getters.syzArray.forEach((ele) => {
+            if (ele.stationId === this.activeTab) {
+                if (!ele.isMute) {
+                this.audio = new Audio(audioPath);
+                this.audio.play();
+                }
+            }
+            });
+        }
+        },
+
+        // 显示某个小红点
+        renderWarningTag(stationId = "") {
         this.$store.getters.syzArray.forEach((ele) => {
-          if (ele.stationId === this.activeTab) {
-            if (!ele.isMute) {
-              this.audio = new Audio(audioPath);
-              this.audio.play();
+            if (ele.id === stationId) {
+            ele.isWarning = "1";
             }
-          }
         });
-      }
-    },
-
-    // 显示某个小红点
-    renderWarningTag(stationId = "") {
-      this.$store.getters.syzArray.forEach((ele) => {
-        if (ele.id === stationId) {
-          ele.isWarning = "1";
-        }
-      });
-      this.pageshowMode++;
-    },
+        this.pageshowMode++;
+        },
 
-    // 清除某个小红点
-    clearWarningTag(stationId = "") {
-      this.$store.getters.syzArray.forEach((ele) => {
-        if (ele.id === stationId) {
-          ele.isWarning = "0";
+        // 清除某个小红点
+        clearWarningTag(stationId = "") {
+        this.$store.getters.syzArray.forEach((ele) => {
+            if (ele.id === stationId) {
+            ele.isWarning = "0";
+            }
+        });
+        this.pageshowMode++;
+        },
+
+        // 切换报警声音开关
+        switchAlarmSound(index) {
+        this.$store.getters.syzArray[index].isMute =
+            !this.$store.getters.syzArray[index].isMute;
+        },
+
+        opened() {
+            this.initAlarm();
+            this.getAllStationtab()
+            this.timmer = setInterval(() => {
+                this.renderAlarm();
+            }, 3000);
+            
+            let starTimerWarn = setInterval(() =>{
+                this.getSyzWarnData()
+            }, 2000)
+            if (this.activeTabStation) {
+                setTimeout(() => {
+                    clearInterval(this.starTimer);
+                this.starTimer = null;
+                this.$store.commit("activeTab", this.activeTabStation);
+                this.renderAlarm(this.activeTabStation, false);
+                    if (this.activeTabStation !== 'all') {
+                        this.activeTab = this.activeTabStation
+                    this.debounce(this.getSvgDataFn(this.activeTabStation), 200)
+                }  
+                }, 100);
+            }
+        },
+
+        closed() {
+            // this.$refs.svgRef[0].closed()
+            // this.$refs.svgRef[1].closed()
+            // this.$refs.svgRef[2].closed()
+            // this.$refs.svgRef[3].closed()
+            // this.$refs.svgRef[4].closed()
+            clearInterval(this.starTimer);
+            clearInterval(this.starTimerWarn);
+            clearInterval(this.timmer);
+            this.starTimer = null
+            this.starTimerWarn = null
+            this.timmer = null;
+            this.$store.commit("activeTab", "");
+            this.$store.commit("syzDialogShow", false);
+        },
+
+        tabClick(res) {
+            clearInterval(this.starTimer);
+            this.starTimer = null;
+            this.$store.commit("activeTab", res.props.name);
+            this.renderAlarm(res.props.name, false);
+            if (res.props.name !== 'all') {
+                this.debounce(this.getSvgDataFn(res.props.name), 200)
+                // this.getSvgDataFn(res.props.name)
+            }
+        },
+        debounce(fn, delay) {
+            var delay = delay || 200;
+            var timer;
+            return function () {
+                var th = this;
+                var args = arguments;
+                if (timer) {
+                    clearTimeout(timer);
+                }
+                timer = setTimeout(function () {
+                    timer = null;
+                    fn.apply(th, args);
+                }, delay);
+            };
+        },
+        throttle(fn, interval) {
+            var last;
+            var timer;
+            var interval = interval || 200;
+            return function () {
+                var th = this;
+                var args = arguments;
+                var now = +new Date();
+                if (last && now - last < interval) {
+                    clearTimeout(timer);
+                    timer = setTimeout(function () {
+                        last = now;
+                        fn.apply(th, args);
+                    }, interval);
+                } else {
+                    last = now;
+                    fn.apply(th, args);
+                }
+            }
         }
-      });
-      this.pageshowMode++;
     },
-
-    // 切换报警声音开关
-    switchAlarmSound(index) {
-      this.$store.getters.syzArray[index].isMute =
-        !this.$store.getters.syzArray[index].isMute;
+    watch: {
+        "$store.state.syzArray"(res) {
+        this.syzArray = res;
+        },
     },
-
-    opened() {
-      this.initAlarm();
-      this.timmer = setInterval(() => {
-        this.renderAlarm();
-      }, 3000);
-    },
-
-    closed() {
-      clearInterval(this.timmer);
-      this.timmer = null;
-      this.$store.commit("activeTab", "");
-      this.$store.commit("syzDialogShow", false);
-    },
-
-    tabClick(res) {
-      this.$store.commit("activeTab", res.props.name);
-      this.renderAlarm(res.props.name, false);
-    },
-  },
-  watch: {
-    "$store.state.syzArray"(res) {
-      this.syzArray = res;
-    },
-  },
 };
 </script>
 
@@ -289,14 +669,93 @@ export default {
   display: flex;
   flex-direction: row;
   background-color: black;
-  width: 100%;
+  width: 98%;
   margin-top: -30px;
-  height: 91vh;
+  height: 90vh;
   position: relative;
   overflow: hidden;
+  margin-left: 44px;
 
   .syzDetailsPaneItem {
     position: relative;
+    .buttonGroup{
+        margin-bottom: 10px;
+        display: flex;
+        // justify-content: end;
+        float: right;
+        .el-button-group{
+            .el-button{
+                min-height: 30px !important;
+            }
+            .showSty{
+                color: #409eff;
+                border-color: #c6e2ff;
+                background-color: #ecf5ff;
+                outline: 0;
+            }
+        }
+    }
+    .warningMaskNew {
+        background-color: rgba(186, 50, 55, 0.5);
+        animation: fade 2000ms infinite;
+        -webkit-animation: fade 2000ms infinite;
+    }
+
+    @keyframes fade {
+    from {
+        opacity: 0.7;
+    }
+
+    50% {
+        opacity: 0.3;
+    }
+
+    to {
+        opacity: 0.7;
+    }
+    }
+
+    @-webkit-keyframes fade {
+    from {
+        opacity: 0.7;
+    }
+
+    50% {
+        opacity: 0.3;
+    }
+
+    to {
+        opacity: 0.7;
+    }
+    }
+    .showAllSvgMsg{
+        width: calc(100% - 15px);
+        height: calc(100% - 15px);
+        // padding: 20px;
+        // margin-bottom: 20px;
+        // background: #3a3a3a;
+        // border: 3px solid #3a3a3a;
+        border: 3px solid #646464;
+        border-radius: 10px;
+        .showAllSvgMsg_top{
+            border-radius: 10px 10px 0 0;
+            height: calc(100% - 40px);
+            width: 100%;
+            // background: #fff;
+        }
+        .showAllSvgMsg_bot{
+            background: #3a3a3a;
+            border-radius: 0 0 8px 8px;
+            height: 40px;
+            text-align: center;
+            span{
+                position: relative;
+                top: 10px;
+                font-weight: bold;
+                color: #fff;
+            }
+        }
+    }
 
     .alarmIconBox {
       position: absolute;
@@ -321,12 +780,12 @@ export default {
     position: relative;
   }
   .movableItem {
-    width: 100% !important;
-    height: 100% !important;
+    // width: 1920PX !important;
+    // height: 800PX !important;
 
     .svg {
-      width: 100%;
-      height: 92%;
+    //   width: 100%;
+    //   height: 92%;
       margin-left: 0;
       margin-top: 8%;
     }
@@ -364,4 +823,5 @@ export default {
     cursor: pointer;
   }
 }
+
 </style>

+ 274 - 104
src/components/matrixBlock.vue

@@ -1,82 +1,118 @@
 <template>
-  <div
-    class="currentScroll"
-    style="
-      display: flex;
-      flex-direction: row;
-      flex-wrap: wrap;
-      height: 100%;
-      overflow-y: scroll;
-    "
-  >
+  <div>
     <div
-      :class="item.active ? 'box-' + item.status : 'unbox-' + item.status"
-      v-for="(item, index) in dataList"
-      :key="index"
-      @click="onSelectHandler(item)"
-      @dblclick="sendMsg(item)"
-      style="margin-right: 8px"
+      class="box"
+      style="display: flex; flex-direction: row; flex-wrap: wrap"
     >
       <div
-        :class="item.active ? 'left-' + item.status : 'unleft-' + item.status"
+        :class="
+          item.active
+            ? 'box-' + item.status
+            : item.flashing && item.status === 5
+            ? 'unbox-flashing-' + item.status
+            : 'unbox-' + item.status
+        "
+        :id="item.windturbineId"
+        v-for="(item, index) in dataList"
+        :key="index"
+        @click="onSelectHandler(item)"
+        @dblclick="sendMsg(item)"
+        style="margin-right: 8px"
       >
-        <div>{{ item.windturbineId.slice(0, 2) }}</div>
-        <div>{{ item.windturbineId.slice(5) }}</div>
-      </div>
-      <div
-        :class="item.active ? 'right-' + item.status : 'unright-' + item.status"
-      >
-        <div class="rightrow">{{ item.windSpeed.toFixed(2) }} m/s</div>
-        <div class="rightrow">{{ item.power.toFixed(2) }} kw</div>
-        <div class="rightrow">
-          {{
-            item.modelId.indexOf("105") >= 0
-              ? (item.rollSpeed * 9.55).toFixed(2)
-              : item.rollSpeed.toFixed(2)
-          }}
-          rpm
+        <div
+          :class="item.active ? 'left-' + item.status : 'unleft-' + item.status"
+        >
+          <div>{{ getName(item, 'top') }}</div>
+          <div>{{ getName(item, 'bot') }}</div>
+          <!-- <div>{{ item.windturbineId.slice(0, 2) }}</div>
+        <div>{{ item.code }}</div> -->
         </div>
-      </div>
-      <div class="locks" v-if="item.lockValue > 0">
-        <el-popover
-          placement="bottom-start"
-          :width="150"
-          trigger="hover"
-          class="popoverBack"
-          :show-arrow="false"
+        <div
+          :class="
+            item.active ? 'right-' + item.status : 'unright-' + item.status
+          "
         >
-          <template #reference>
-            <img class="lock" src="../assets/img/type/lock.png" alt="" />
-          </template>
-          <input
-            class="lock_input"
-            type="text"
-            placeholder=""
-            :value="
-              item.lockValue === 9 ? item.lockValues : options[item.lockValue]
-            "
-            disabled
+          <div class="rightrow">{{ item.windSpeed.toFixed(2) }} m/s</div>
+
+          <div class="rightrow">{{ item.power.toFixed(2) }} kw</div>
+
+          <div class="rightrow">
+            {{
+              item.modelId.indexOf("105") >= 0
+                ? (item.rollSpeed * 9.55).toFixed(2)
+                : item.rollSpeed.toFixed(2)
+            }}
+            rpm
+          </div>
+        </div>
+        <div class="duration">
+          <el-popover
+            placement="bottom-start"
+            :width="200"
+            trigger="hover"
+            class="durationPopover"
+            :show-arrow="false"
+            @show="handleDeal(item.ts)"
+          >
+            <template #reference>
+              <img
+                :class="item.lockValue > 0 ? 'durationImgs' : 'durationImg'"
+                src="../assets/img/type/duration.png"
+                alt=""
+              />
+            </template>
+            <input
+              class="lock_inputs"
+              type="text"
+              placeholder=""
+              :value="showVlaues"
+              disabled
+            />
+          </el-popover>
+        </div>
+        <div class="locks" v-if="item.lockValue > 0">
+          <el-popover
+            placement="bottom-start"
+            :width="150"
+            trigger="hover"
+            class="popoverBack"
+            :show-arrow="false"
+          >
+            <template #reference>
+              <img class="lock" src="../assets/img/type/lock.png" alt="" />
+            </template>
+            <input
+              class="lock_input"
+              type="text"
+              placeholder=""
+              :value="
+                item.lockValue === 9 ? item.lockValues : options[item.lockValue]
+              "
+              disabled
+            />
+          </el-popover>
+        </div>
+        <div class="locks" v-if="item.reasonType">
+          <img
+            class="lock"
+            src="../assets/img/type/electricityRestrictions.png"
+            alt=""
           />
-        </el-popover>
-      </div>
-      <div class="locks" v-if="item.reasonType">
-        <img
-          class="lock"
-          src="../assets/img/type/electricityRestrictions.png"
-          alt=""
-        />
+        </div>
       </div>
     </div>
+    <WindturbineDetailPages
+      v-model="dialogVisible"
+      :showSvg="showSvg"
+      @close="handleClose"
+      :windturbine="currentWindturbine"
+    ></WindturbineDetailPages>
   </div>
-  <WindturbineDetailPages
-    v-model="dialogVisible"
-    :showSvg="showSvg"
-    @close="handleClose"
-    :windturbine="currentWindturbine"
-  ></WindturbineDetailPages>
 </template>
 <script>
 import WindturbineDetailPages from "./WindturbineDetailPages.vue";
+import api from "api/index";
+import dayjs from "dayjs";
 export default {
   components: {
     WindturbineDetailPages,
@@ -90,16 +126,63 @@ export default {
     },
     area: String,
   },
-  mounted() {},
+  mounted() {
+    // this.getWindturbineFdc();
+  },
   updated() {},
   methods: {
+    getName(item, type) {
+        // debugger
+        let name = ''
+        if (type === 'top') {
+            if (item.windturbineId) {
+                name = item.windturbineId.slice(0, 2)
+            }
+        } else {
+            if (item.windturbineId) {
+                name = item.windturbineId.slice(item.windturbineId.indexOf('_')+1)
+            }
+        }
+        return name
+    },
+    handleDeal(val) {
+      let data = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
+      this.showVlaues = this.timeFn(data);
+      // return `该状态共持续:`
+    },
+
+    timeFn(d1) {
+      //di作为一个变量传进来
+      //如果时间格式是正确的,那下面这一步转化时间格式就可以不用了
+      var dateBegin = new Date(d1.replace(/-/g, "/")); //将-转化为/,使用new Date
+      var dateEnd = new Date(); //获取当前时间
+      var dateDiff = dateEnd.getTime() - dateBegin.getTime(); //时间差的毫秒数
+      var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000)); //计算出相差天数
+      var leave1 = dateDiff % (24 * 3600 * 1000); //计算天数后剩余的毫秒数
+      var hours = Math.floor(leave1 / (3600 * 1000)); //计算出小时数
+      //计算相差分钟数
+      var leave2 = leave1 % (3600 * 1000); //计算小时数后剩余的毫秒数
+      var minutes = Math.floor(leave2 / (60 * 1000)); //计算相差分钟数
+      //计算相差秒数
+      var leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数
+      var seconds = Math.round(leave3 / 1000);
+      return `持续时长:${dayDiff !== 0 ? dayDiff + "天" : ""}${
+        hours !== 0 ? hours + "小时" : ""
+      }${minutes !== 0 ? minutes + "分钟" : ""}${
+        seconds !== 0 ? seconds + "秒" : ""
+      }`;
+    },
+    // getWindturbineFdc() {
+    //   api.getWindturbineFdc().then((res) => {
+    //     this.station = res.data;
+    //   });
+    // },
     onSelectHandler(values) {
       if (this.area === "problem") {
         this.$emit("problem-click", values);
       } else {
         this.$emit("choose-click", values);
       }
-      // values.active = !values.active;
     },
     sendMsg: function (itm) {
       // this.dialogVisible = true;
@@ -116,6 +199,8 @@ export default {
       dialogVisible: false,
       showSvg: false,
       currentWindturbine: {},
+      showVlaues: "",
+      // station: [],
       options: {
         8: "检修",
         7: "故障维修",
@@ -133,10 +218,24 @@ export default {
   width: 10px;
   height: 10px;
   position: relative;
-  right: 6px;
+  right: 2px;
   top: -15px;
 }
 
+.durationImg {
+  width: 15px;
+  height: 15px;
+  position: relative;
+  right: 5px;
+  top: -15px;
+}
+.durationImgs {
+  width: 15px;
+  height: 15px;
+  position: relative;
+  right: 5px;
+  top: -15px;
+}
 .lock-on {
   width: 0px;
   height: 0px;
@@ -156,13 +255,46 @@ export default {
   z-index: 999;
 }
 
+.duration {
+  width: 15px;
+  height: 15px;
+  position: relative;
+  visibility: hidden;
+}
+.unbox-1:hover .duration {
+  visibility: visible;
+}
+.unbox-2:hover .duration {
+  visibility: visible;
+}
+.unbox-3:hover .duration {
+  visibility: visible;
+}
+.unbox-4:hover .duration {
+  visibility: visible;
+}
+.unbox-5:hover .duration {
+  visibility: visible;
+}
+.unbox-6:hover .duration {
+  visibility: visible;
+}
+.unbox-7:hover .duration {
+  visibility: visible;
+}
+
 .lock_input {
   width: 140px;
   background-color: #292929;
   height: 40px;
   color: #ffffff;
 }
-
+.lock_inputs {
+  width: 200px;
+  background-color: #292929;
+  height: 40px;
+  color: #ffffff;
+}
 .box-0 {
   width: 135px;
   height: 50px;
@@ -191,7 +323,7 @@ export default {
 }
 
 .left-0 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(255, 255, 255, 1);
@@ -204,7 +336,7 @@ export default {
 }
 
 .unleft-0 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(255, 255, 255, 1);
@@ -217,7 +349,7 @@ export default {
 }
 
 .right-0 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(255, 255, 255, 1);
@@ -228,7 +360,7 @@ export default {
 }
 
 .unright-0 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(255, 255, 255, 1);
@@ -266,7 +398,7 @@ export default {
 }
 
 .left-1 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(197, 48, 200, 1);
@@ -279,7 +411,7 @@ export default {
 }
 
 .unleft-1 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(197, 48, 200, 1);
@@ -292,7 +424,7 @@ export default {
 }
 
 .right-1 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(197, 48, 200, 1);
@@ -303,7 +435,7 @@ export default {
 }
 
 .unright-1 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(197, 48, 200, 1);
@@ -341,7 +473,7 @@ export default {
 }
 
 .left-2 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(05, 187, 76, 1);
@@ -354,7 +486,7 @@ export default {
 }
 
 .unleft-2 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(05, 187, 76, 1);
@@ -367,7 +499,7 @@ export default {
 }
 
 .right-2 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(05, 187, 76, 1);
@@ -378,7 +510,7 @@ export default {
 }
 
 .unright-2 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(05, 187, 76, 1);
@@ -416,7 +548,7 @@ export default {
 }
 
 .left-3 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(05, 187, 76, 1);
@@ -429,7 +561,7 @@ export default {
 }
 
 .unleft-3 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(05, 187, 76, 1);
@@ -442,7 +574,7 @@ export default {
 }
 
 .right-3 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(05, 187, 76, 1);
@@ -453,7 +585,7 @@ export default {
 }
 
 .unright-3 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(05, 187, 76, 1);
@@ -491,7 +623,7 @@ export default {
 }
 
 .left-4 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(75, 85, 174, 1);
@@ -504,7 +636,7 @@ export default {
 }
 
 .unleft-4 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(75, 85, 174, 1);
@@ -517,7 +649,7 @@ export default {
 }
 
 .right-4 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(75, 85, 174, 1);
@@ -528,7 +660,7 @@ export default {
 }
 
 .unright-4 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(75, 85, 174, 1);
@@ -539,10 +671,10 @@ export default {
 }
 
 .box-5 {
-  width: 133px;
-  height: 48px;
+  width: 135px;
+  height: 50px;
   color: #ffffff;
-  border: 2px solid rgba(186, 50, 55, 1);
+  border: 1px solid rgba(186, 50, 55, 1);
   background-color: rgba(186, 50, 55, 0.05);
   display: flex;
   flex-direction: row;
@@ -552,6 +684,44 @@ export default {
   box-shadow: 0px 0px 6px #ff1313;
 }
 
+@keyframes fade {
+  from {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0.6;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes fade {
+  from {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0.6;
+  }
+  to {
+    opacity: 1;
+  }
+}
+
+.unbox-flashing-5 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(186, 50, 55, 1);
+  background-color: rgba(186, 50, 55, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  animation: fade 1600ms infinite;
+  -webkit-animation: fade 1600ms infinite;
+}
+
 .unbox-5 {
   width: 135px;
   height: 50px;
@@ -566,7 +736,7 @@ export default {
 }
 
 .left-5 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(186, 50, 55, 1);
@@ -579,7 +749,7 @@ export default {
 }
 
 .unleft-5 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(186, 50, 55, 1);
@@ -592,7 +762,7 @@ export default {
 }
 
 .right-5 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(186, 50, 55, 1);
@@ -603,7 +773,7 @@ export default {
 }
 
 .unright-5 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(186, 50, 55, 1);
@@ -641,7 +811,7 @@ export default {
 }
 
 .left-6 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(225, 125, 36, 1);
@@ -654,7 +824,7 @@ export default {
 }
 
 .unleft-6 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(225, 125, 36, 1);
@@ -667,7 +837,7 @@ export default {
 }
 
 .right-6 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(225, 125, 36, 1);
@@ -678,7 +848,7 @@ export default {
 }
 
 .unright-6 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(225, 125, 36, 1);
@@ -716,7 +886,7 @@ export default {
 }
 
 .left-7 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(96, 103, 105, 1);
@@ -729,7 +899,7 @@ export default {
 }
 
 .unleft-7 {
-  width: 40%;
+  width: 35%;
   height: 100%;
   font-size: 12px;
   color: rgba(96, 103, 105, 1);
@@ -742,7 +912,7 @@ export default {
 }
 
 .right-7 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(96, 103, 105, 1);
@@ -753,7 +923,7 @@ export default {
 }
 
 .unright-7 {
-  width: 60%;
+  width: 69%;
   height: 100%;
   font-size: 12px;
   color: rgba(96, 103, 105, 1);

+ 926 - 0
src/components/matrixBlockPv.vue

@@ -0,0 +1,926 @@
+<template>
+  <div>
+    <div
+      class="box"
+      style="display: flex; flex-direction: row; flex-wrap: wrap"
+    >
+    <!-- @click="onSelectHandler(item)" -->
+      <div
+        :class="
+          item.active
+            ? 'box-' + item.status
+            : item.flashing && item.status === 5
+            ? 'unbox-flashing-' + item.status
+            : 'unbox-' + item.status
+        "
+        :id="item.windturbineId"
+        v-for="(item, index) in dataList"
+        :key="index"
+        
+        @dblclick="sendMsg(item)"
+        style="margin-right: 8px"
+      >
+        <div
+          :class="item.active ? 'left-' + item.status : 'unleft-' + item.status"
+        >
+          <div>{{ getName(item, 'top') }}</div>
+          <div>{{ getName(item, 'bot') }}</div>
+          <!-- <div>{{ item.windturbineId.slice(0, 2) }}</div>
+        <div>{{ item.code }}</div> -->
+        </div>
+        <div
+          :class="
+            item.active ? 'right-' + item.status : 'unright-' + item.status
+          "
+        >
+            <div class="rightrow">{{ item.i.toFixed(2) }} A</div>
+
+            <div class="rightrow">{{ item.u.toFixed(2) }} V</div>
+
+            <div class="rightrow">{{ item.p.toFixed(2) }} kw</div>
+        </div>
+        <div class="duration">
+          <el-popover
+            placement="bottom-start"
+            :width="200"
+            trigger="hover"
+            class="durationPopover"
+            :show-arrow="false"
+            @show="handleDeal(item.ts)"
+          >
+            <template #reference>
+              <img
+                :class="item.lockValue > 0 ? 'durationImgs' : 'durationImg'"
+                src="../assets/img/type/duration.png"
+                alt=""
+              />
+            </template>
+            <input
+              class="lock_inputs"
+              type="text"
+              placeholder=""
+              :value="showVlaues"
+              disabled
+            />
+          </el-popover>
+        </div>
+        <div class="locks" v-if="item.lockValue > 0">
+          <el-popover
+            placement="bottom-start"
+            :width="150"
+            trigger="hover"
+            class="popoverBack"
+            :show-arrow="false"
+          >
+            <template #reference>
+              <img class="lock" src="../assets/img/type/lock.png" alt="" />
+            </template>
+            <input
+              class="lock_input"
+              type="text"
+              placeholder=""
+              :value="
+                item.lockValue === 9 ? item.lockValues : options[item.lockValue]
+              "
+              disabled
+            />
+          </el-popover>
+        </div>
+        <div class="locks" v-if="item.reasonType">
+          <img
+            class="lock"
+            src="../assets/img/type/electricityRestrictions.png"
+            alt=""
+          />
+        </div>
+      </div>
+    </div>
+    <WindturbineDetailPages
+      v-model="dialogVisible"
+      :showSvg="showSvg"
+      @close="handleClose"
+      :windturbine="currentWindturbine"
+    ></WindturbineDetailPages>
+  </div>
+</template>
+<script>
+import WindturbineDetailPages from "./WindturbineDetailPages.vue";
+import api from "api/index";
+import dayjs from "dayjs";
+export default {
+  components: {
+    WindturbineDetailPages,
+  },
+  props: {
+    dataList: {
+      type: Array,
+      default: () => {
+        return [];
+      },
+    },
+    area: String,
+  },
+  mounted() {
+    // this.getWindturbineFdc();
+  },
+  updated() {},
+  methods: {
+    getName(item, type) {
+        let name = ''
+        if (item.id) {
+            if (type === 'top') {
+                name = item.id.slice(0, item.id.indexOf('_'))
+            } else {
+                name = item.id.slice(item.id.indexOf('_'))
+            }
+        }
+        return name
+    },
+    handleDeal(val) {
+      let data = dayjs(val).format("YYYY-MM-DD HH:mm:ss");
+      this.showVlaues = this.timeFn(data);
+      // return `该状态共持续:`
+    },
+
+    timeFn(d1) {
+      //di作为一个变量传进来
+      //如果时间格式是正确的,那下面这一步转化时间格式就可以不用了
+      var dateBegin = new Date(d1.replace(/-/g, "/")); //将-转化为/,使用new Date
+      var dateEnd = new Date(); //获取当前时间
+      var dateDiff = dateEnd.getTime() - dateBegin.getTime(); //时间差的毫秒数
+      var dayDiff = Math.floor(dateDiff / (24 * 3600 * 1000)); //计算出相差天数
+      var leave1 = dateDiff % (24 * 3600 * 1000); //计算天数后剩余的毫秒数
+      var hours = Math.floor(leave1 / (3600 * 1000)); //计算出小时数
+      //计算相差分钟数
+      var leave2 = leave1 % (3600 * 1000); //计算小时数后剩余的毫秒数
+      var minutes = Math.floor(leave2 / (60 * 1000)); //计算相差分钟数
+      //计算相差秒数
+      var leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数
+      var seconds = Math.round(leave3 / 1000);
+      return `持续时长:${dayDiff !== 0 ? dayDiff + "天" : ""}${
+        hours !== 0 ? hours + "小时" : ""
+      }${minutes !== 0 ? minutes + "分钟" : ""}${
+        seconds !== 0 ? seconds + "秒" : ""
+      }`;
+    },
+    // getWindturbineFdc() {
+    //   api.getWindturbineFdc().then((res) => {
+    //     this.station = res.data;
+    //   });
+    // },
+    onSelectHandler(values) {
+      if (this.area === "problem") {
+        this.$emit("problem-click", values);
+      } else {
+        this.$emit("choose-click", values);
+      }
+    },
+    sendMsg: function (itm) {
+      // this.dialogVisible = true;
+      this.$emit("on-click", itm);
+      // this.currentWindturbine = itm;
+    },
+    handleClose() {
+      this.dialogVisible = false;
+      this.showSvg = false;
+    },
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      showSvg: false,
+      currentWindturbine: {},
+      showVlaues: "",
+      // station: [],
+      options: {
+        8: "检修",
+        7: "故障维修",
+        2: "场内受累检修",
+        3: "场内受累故障",
+        4: "场外受累电网",
+        5: "场外受累天气",
+      },
+    };
+  },
+};
+</script>
+<style scoped>
+.lock {
+  width: 10px;
+  height: 10px;
+  position: relative;
+  right: 2px;
+  top: -15px;
+}
+
+.durationImg {
+  width: 15px;
+  height: 15px;
+  position: relative;
+  right: 5px;
+  top: -15px;
+}
+.durationImgs {
+  width: 15px;
+  height: 15px;
+  position: relative;
+  right: 5px;
+  top: -15px;
+}
+.lock-on {
+  width: 0px;
+  height: 0px;
+  opacity: 0;
+}
+
+.locks:hover .lock-on {
+  position: fixed;
+  display: flex;
+  align-items: center;
+  width: 80px;
+  height: 30px;
+  border: 1px solid #999999;
+  background-color: #999999;
+  opacity: 1;
+  color: #ffffff;
+  z-index: 999;
+}
+
+.duration {
+  width: 15px;
+  height: 15px;
+  position: relative;
+  visibility: hidden;
+}
+.unbox-1:hover .duration {
+  visibility: visible;
+}
+.unbox-2:hover .duration {
+  visibility: visible;
+}
+.unbox-3:hover .duration {
+  visibility: visible;
+}
+.unbox-4:hover .duration {
+  visibility: visible;
+}
+.unbox-5:hover .duration {
+  visibility: visible;
+}
+.unbox-6:hover .duration {
+  visibility: visible;
+}
+.unbox-7:hover .duration {
+  visibility: visible;
+}
+
+.lock_input {
+  width: 140px;
+  background-color: #292929;
+  height: 40px;
+  color: #ffffff;
+}
+.lock_inputs {
+  width: 200px;
+  background-color: #292929;
+  height: 40px;
+  color: #ffffff;
+}
+.box-0 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(05, 187, 76, 1);
+  background-color: rgba(255, 255, 255, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #09e45e;
+}
+
+.unbox-0 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(05, 187, 76, 1);
+  background-color: rgba(05, 187, 76, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+}
+
+.left-0 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-0 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-0 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-0 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(05, 187, 76, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-1 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(75, 85, 174, 1);
+  background-color: rgba(75, 85, 174, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #6876f2;
+}
+
+.unbox-1 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(75, 85, 174, 1);
+  background-color: rgba(75, 85, 174, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+}
+
+.left-1 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-1 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-1 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-1 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-2, .box-4, .box-5 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(186, 50, 55, 1);
+  background-color: rgba(186, 50, 55, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #ff1313;
+}
+
+.unbox-2, .unbox-4, .unbox-5 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(186, 50, 55, 1);
+  background-color: rgba(186, 50, 55, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+}
+
+.left-2, .left-4, .left-5 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-2, .unleft-4, .unleft-5 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-2, .right-4, .right-5 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-2, .unright-4, .unright-5 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-3 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(225, 125, 36, 1);
+  background-color: rgba(225, 125, 36, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #f28627;
+}
+
+.unbox-3 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(225, 125, 36, 1);
+  background-color: rgba(225, 125, 36, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+}
+
+.left-3 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-3 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-3 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-3 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-4 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(75, 85, 174, 1);
+  background-color: rgba(75, 85, 174, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #6876f2;
+}
+
+.unbox-4 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(75, 85, 174, 1);
+  background-color: rgba(75, 85, 174, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+}
+
+.left-4 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-4 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-4 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-4 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(75, 85, 174, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-5 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(186, 50, 55, 1);
+  background-color: rgba(186, 50, 55, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #ff1313;
+}
+
+@keyframes fade {
+  from {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0.6;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes fade {
+  from {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0.6;
+  }
+  to {
+    opacity: 1;
+  }
+}
+
+.unbox-flashing-5 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(186, 50, 55, 1);
+  background-color: rgba(186, 50, 55, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  animation: fade 1600ms infinite;
+  -webkit-animation: fade 1600ms infinite;
+}
+
+.unbox-5 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(186, 50, 55, 1);
+  background-color: rgba(186, 50, 55, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+}
+
+.left-5 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-5 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-5 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-5 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(186, 50, 55, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-6 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(225, 125, 36, 1);
+  background-color: rgba(225, 125, 36, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #f28627;
+}
+
+.unbox-6 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(225, 125, 36, 1);
+  background-color: rgba(225, 125, 36, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+}
+
+.left-6 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-6 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-6 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-6 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(225, 125, 36, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.box-7 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(96, 103, 105, 1);
+  background-color: rgba(96, 103, 105, 0.05);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+  box-shadow: 0px 0px 6px #ffffff;
+}
+
+.unbox-7 {
+  width: 135px;
+  height: 50px;
+  color: #ffffff;
+  border: 1px solid rgba(96, 103, 105, 1);
+  background-color: rgba(96, 103, 105, 0.2);
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-right: 5px;
+  margin-top: 10px;
+}
+
+.left-7 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(96, 103, 105, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.unleft-7 {
+  width: 35%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(96, 103, 105, 1);
+  font-weight: 600;
+  line-height: 20px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.right-7 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(96, 103, 105, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.unright-7 {
+  width: 69%;
+  height: 100%;
+  font-size: 12px;
+  color: rgba(96, 103, 105, 1);
+  line-height: 15px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+</style>

+ 380 - 385
src/components/modeControl/detailPages.vue

@@ -1,408 +1,403 @@
 <template>
-	<el-dialog width="55%" @closed="closed()" :show-close="false" class="my-info-dialog">
-		<template #title>
-			<div class="showTitle">
-				<img class="titleImg" src="../../assets/img/controlcenter/daraTrue.png" alt="">
-				<div class="titles">国电电力宁夏新能源开发有限公司</div>
-			</div>
-		</template>
-		<div class="body">
-			<div class="dataList">
-				<div class="data">
-					<div class="name">健康指数:</div>
-					<div class="num">{{showDate?.healthIndex?.value}}</div>
-				</div>
-				<div class="data">
-					<div class="name">资源指数:</div>
-					<div class="num">{{showDate?.resourceIndex?.value}}</div>
-				</div>
-				<div class="data">
-					<div class="name">风能利用率:</div>
-					<div class="num">{{showDate?.windEnergyRate?.value}}%</div>
-				</div>
-				<div class="data">
-					<div class="name">曲线跟随率:</div>
-					<div class="num">{{showDate?.curveFollowingRate?.value}}%</div>
-				</div>
-				<div class="data">
-					<div class="name">实际功率:</div>
-					<div class="num">{{showDate?.realTimePower?.value}}</div>
-					<div class="unit">MW</div>
-				</div>
-				<div class="data">
-					<div class="name">理论功率:</div>
-					<div class="num">{{showDate?.theoreticalPower?.value}}</div>
-					<div class="unit" @click='ChangeColor()'>MW</div>
-				</div>
-				<div class="data">
-					<div class="name">AGC有功设定:</div>
-					<div class="num">{{showDate?.agcPowerSet?.value}}</div>
-					<div class="unit" @click='ChangeColors()'>MW</div>
-				</div>
-			</div>
-			<div id="totleEcharts" class="echarts"></div>
-			<!-- <MultipleLineChart height="400px" :units="powerLineChartData.units" :list="powerLineChartData.value" :colors="colors"
+  <el-dialog
+    width="55%"
+    @opened="opened()"
+    @closed="closed()"
+    :show-close="false"
+    class="my-info-dialog"
+  >
+    <template #title>
+      <div class="showTitle">
+        <img
+          class="titleImg"
+          src="../../assets/img/controlcenter/daraTrue.png"
+          alt=""
+        />
+        <div class="titles">国电电力宁夏新能源开发有限公司</div>
+      </div>
+    </template>
+    <div class="body">
+      <div class="dataList">
+        <div class="data">
+          <div class="name">健康指数:</div>
+          <div class="num">{{ showDate?.healthIndex?.value }}</div>
+        </div>
+        <div class="data">
+          <div class="name">资源指数:</div>
+          <div class="num">{{ showDate?.resourceIndex?.value }}</div>
+        </div>
+        <div class="data">
+          <div class="name">风能利用率:</div>
+          <div class="num">{{ showDate?.windEnergyRate?.value }}%</div>
+        </div>
+        <div class="data">
+          <div class="name">曲线跟随率:</div>
+          <div class="num">{{ showDate?.curveFollowingRate?.value }}%</div>
+        </div>
+        <div class="data">
+          <div class="name">实际功率:</div>
+          <div class="num">{{ showDate?.realTimePower?.value }}</div>
+          <div class="unit">MW</div>
+        </div>
+        <div class="data">
+          <div class="name">理论功率:</div>
+          <div class="num">{{ showDate?.theoreticalPower?.value }}</div>
+          <div class="unit" @click="ChangeColor()">MW</div>
+        </div>
+        <div class="data">
+          <div class="name">AGC有功设定:</div>
+          <div class="num">{{ showDate?.agcPowerSet?.value }}</div>
+          <div class="unit" @click="ChangeColors()">MW</div>
+        </div>
+      </div>
+      <div id="totleEcharts" class="echarts"></div>
+      <!-- <MultipleLineChart height="400px" :units="powerLineChartData.units" :list="powerLineChartData.value" :colors="colors"
 				:showLegend="true" /> -->
-		</div>
-	</el-dialog>
+    </div>
+  </el-dialog>
 </template>
 
 <script>
-	import MultipleLineChart from "../focus/multiple-line-chart.vue";
-	import MessageBridge from 'utils/MessageBridge'
-	import dayjs from 'dayjs'
-	import api from "api/index";
-	import * as echarts from "echarts";
-	export default {
-		components: {
-			MultipleLineChart
-		},
-		props: {
-			stationName: {
-				type: String,
-				default: ''
-			},
-			data: {
-				type: Array
-			},
-		},
-		created() {
-			// this.initData()
-		},
-		mounted() {
-			this.initData()
-		},
-		data() {
-			return {
-				// 定时器
-				timer: "",
-				colors: ["rgba(75, 85, 174, 1)", "rgba(05, 187, 76, 1)"],
-				showDate: {},
-				chartData: {
-					units: [""],
-					value: [
-						{
-							title: "实际功率(MW)",
-							yAxisIndex: 0,
-							value: []
-						},
-						{
-							title: "理论功率(MW)",
-							yAxisIndex: 0,
-							value: []
-						},
-					],
-				},
-				timeData: [],
-				PowerSet: [],
-				ActualPower: [],
-				index: 0,
-				powerLineChartData: {},
-			};
-		},
-		methods: {
-			initData() {
-				let mb = MessageBridge.getInstance();
-				let vs = [{ key: "/topic/title-info", action: this.getMessage }];
-				mb.register(vs);
-			},
-			getMessage(msg) {
-				let data = JSON.parse(msg)
-				data.healthIndex.value = Number(data.healthIndex.value).toFixed(0)
-				data.resourceIndex.value = Number(data.resourceIndex.value).toFixed(0)
-				data.realTimePower.value = data.realTimePower.value.toFixed(2)
-				data.theoreticalPower.value = data.theoreticalPower.value.toFixed(2)
-				data.agcPowerSet.value = data.agcPowerSet.value.toFixed(2)
-				data.windEnergyRate.value = data.windEnergyRate.value.toFixed(2)
-				data.curveFollowingRate.value = data.curveFollowingRate.value.toFixed(2)
-				this.showDate = data
-			},
-			async getDate() {
-				await this.getPower({
-					PowerSet: 'JSFW.NX_GD_FDC_XX_XX_XXX_XXX_CI0135',
-					name: 'PowerSet',
-				})
-				await this.getPower({
-					ActualPower: 'JSFW.NX_GD_FDC_XX_XX_XXX_XXX_CI0192',
-					name: 'ActualPower',
-				})
-				this.timer = setTimeout(() => {
-					this.getDate()
-				}, 60000);
-			},
-			getPower(values) {
-				let date = new Date()
-				let endTs = date.getTime();
-				let startTs = endTs - 28800000;
-				let names = values.name
-				// 	this.powerLineChartData = this.chartData;
-				api.getPower({
-					tagName: values.PowerSet ? values.PowerSet : values.ActualPower,
-					startTs: startTs,
-					endTs: endTs,
-					interval: 60,
-				}).then(res => {
-					if (res) {
-						if (names === 'PowerSet') {
-							let list = []
-							res.data.forEach(item => {
-								list.push({
-									text: dayjs(item.ts).format('hh:mm'),
-									value: parseFloat((item.doubleValue).toFixed(2))
-								})
-								this.chartData.value[0].value = list
-							})
-						} else {
-							let list = []
-							res.data.forEach(item => {
-								list.push({
-									text: dayjs(item.ts).format('hh:mm'),
-									value: (parseFloat((item.doubleValue).toFixed(2)) / 1000)
-								})
-								this.chartData.value[1].value = list
-							})
-						}
-						// this.powerLineChartData = this.chartData;
-						this.totleErtcher(this.chartData)
-					}
-				})
-			},
-			totleErtcher(chartData) {
-				console.log(document.getElementById('totleEcharts'));
-				let chartDom = document.getElementById('totleEcharts');
-				let myChart = echarts.init(chartDom, '#ffffff');
-				let option;
-				option = {
-					legend: {
-						show: true,
-						data: chartData.value.map((t) => {
-							return t.title;
-						}),
-						right: 56,
-						icon: "circle",
-						itemWidth: 6,
-						inactiveColor: '#606769',
-						textStyle: {
-							color: '#B3BDC0',
-							fontSize: 12,
-						},
-					},
-					xAxis: [
-						{
-							type: "category",
-							boundaryGap: false,
-							axisLabel: {
-								interval: 60,
-								showMinLabel: true,
-								showMaxLabel: true,
-								formatter: "{value}",
-								fontSize: 14,
-								textStyle: {
-									color: '#606769',
-								},
-							},
-							axisLine: {
-								show: false,
-							},
-							data: chartData.value[0].value.map(item => {
-								return item.text;
-							}),
-						},
-					],
-					yAxis: {
-						type: "value",
-						axisLabel: {
-							formatter: "{value}",
-							fontSize: 14,
-						},
-						axisLine: {
-							show: false,
-						},
-						splitLine: {
-							show: true,
-							lineStyle: {
-								color: '#606769',
-								type: "dashed",
-							},
-						},
-					},
-					series: [{
-						name: chartData.value[0].title,
-						smooth: true,
-						showSymbol: false,
-						data: chartData.value[0].value.map(item => {
-							return item.value;
-						}),
-						type: 'line',
-						lineStyle: {
-							normal: {
-								color: 'rgba(75, 85, 174, 1)',
-								width: 1,
-							},
-						},
-					},
-					{
-						name: chartData.value[1].title,
-						smooth: true,
-						showSymbol: false,
-						data: chartData.value[1].value.map(item => {
-							return item.value;
-						}),
-						type: 'line',
-						lineStyle: {
-							normal: {
-								color: 'rgba(05, 187, 76, 1)',
-								width: 1,
-							},
-						},
-					}]
-				};
+import MultipleLineChart from "../focus/multiple-line-chart.vue";
+import MessageBridge from "utils/MessageBridge";
+import dayjs from "dayjs";
+import api from "api/index";
+import * as echarts from "echarts";
+export default {
+  components: {
+    MultipleLineChart,
+  },
+  props: {
+    stationName: {
+      type: String,
+      default: "",
+    },
+    data: {
+      type: Array,
+    },
+  },
+  created() {},
+  mounted() {},
+  data() {
+    return {
+      // 定时器
+      timer: "",
+      colors: ["rgba(75, 85, 174, 1)", "rgba(05, 187, 76, 1)"],
+      showDate: {},
+      chartData: {
+        units: [""],
+        value: [
+          {
+            title: "实际功率(MW)",
+            yAxisIndex: 0,
+            value: [],
+          },
+          {
+            title: "理论功率(MW)",
+            yAxisIndex: 0,
+            value: [],
+          },
+        ],
+      },
+      timeData: [],
+      PowerSet: [],
+      ActualPower: [],
+      index: 0,
+      powerLineChartData: {},
+      intervals: null,
+    };
+  },
+  methods: {
+    opened() {
+      this.getMessage();
+      this.intervals = setInterval(this.getMessage, 10000);
+    },
+    getMessage() {
+      api.stationOverview().then((res) => {
+        let data = res.data;
+        data.healthIndex.value = Number(data.healthIndex.value).toFixed(0);
+        data.resourceIndex.value = Number(data.resourceIndex.value).toFixed(0);
+        data.realTimePower.value = data.realTimePower.value.toFixed(2);
+        data.theoreticalPower.value = data.theoreticalPower.value.toFixed(2);
+        data.agcPowerSet.value = data.agcPowerSet.value.toFixed(2);
+        data.windEnergyRate.value = data.windEnergyRate.value.toFixed(2);
+        data.curveFollowingRate.value =
+          data.curveFollowingRate.value.toFixed(2);
+        this.showDate = data;
+      });
+    },
+    async getDate() {
+      await this.getPower({
+        PowerSet: "JSFW.NX_GD_FDC_XX_XX_XXX_XXX_CI0135",
+        name: "PowerSet",
+      });
+      await this.getPower({
+        ActualPower: "JSFW.NX_GD_FDC_XX_XX_XXX_XXX_CI0192",
+        name: "ActualPower",
+      });
+      this.timer = setTimeout(() => {
+        this.getDate();
+      }, 60000);
+    },
+    getPower(values) {
+      let date = new Date();
+      let endTs = date.getTime();
+      let startTs = endTs - 28800000;
+      let names = values.name;
+      api
+        .getPower({
+          tagName: values.PowerSet ? values.PowerSet : values.ActualPower,
+          startTs: startTs,
+          endTs: endTs,
+          interval: 60,
+        })
+        .then((res) => {
+          if (res) {
+            if (names === "ActualPower") {
+              let list = [];
+              res.data.forEach((item) => {
+                list.push({
+                  text: dayjs(item.ts).format("HH:mm"),
+                  value: parseFloat(item.doubleValue.toFixed(2)),
+                });
+                this.chartData.value[0].value = list;
+              });
+            } else {
+              let list = [];
+              res.data.forEach((item) => {
+                list.push({
+                  text: dayjs(item.ts).format("HH:mm"),
+                  value: parseFloat(item.doubleValue.toFixed(2) / 1000),
+                });
+                this.chartData.value[1].value = list;
+              });
+            }
+            this.totleErtcher(this.chartData);
+          }
+        });
+    },
+    totleErtcher(chartData) {
+      console.log(document.getElementById("totleEcharts"));
+      let chartDom = document.getElementById("totleEcharts");
+      let myChart = echarts.init(chartDom, "#ffffff");
+      let option;
+      option = {
+        tooltip: {
+          trigger: "axis",
+        },
+        legend: {
+          show: true,
+          data: chartData.value.map((t) => {
+            return t.title;
+          }),
+          right: 56,
+          icon: "circle",
+          itemWidth: 6,
+          inactiveColor: "#606769",
+          textStyle: {
+            color: "#B3BDC0",
+            fontSize: 12,
+          },
+        },
+        xAxis: [
+          {
+            type: "category",
+            boundaryGap: false,
+            axisLabel: {
+              interval: 60,
+              showMinLabel: true,
+              showMaxLabel: true,
+              formatter: "{value}",
+              fontSize: 14,
+              textStyle: {
+                color: "#606769",
+              },
+            },
+            axisLine: {
+              show: false,
+            },
+            data: chartData.value[0].value.map((item) => {
+              return item.text;
+            }),
+          },
+        ],
+        yAxis: {
+          type: "value",
+          axisLabel: {
+            formatter: "{value}",
+            fontSize: 14,
+          },
+          axisLine: {
+            show: false,
+          },
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "#606769",
+              type: "dashed",
+            },
+          },
+        },
+        series: [
+          {
+            name: chartData.value[0].title,
+            smooth: true,
+            showSymbol: false,
+            data: chartData.value[0].value.map((item) => {
+              return item.value;
+            }),
+            type: "line",
+            lineStyle: {
+              normal: {
+                color: "rgba(75, 85, 174, 1)",
+                width: 1,
+              },
+            },
+          },
+          {
+            name: chartData.value[1].title,
+            smooth: true,
+            showSymbol: false,
+            data: chartData.value[1].value.map((item) => {
+              return item.value;
+            }),
+            type: "line",
+            lineStyle: {
+              normal: {
+                color: "rgba(05, 187, 76, 1)",
+                width: 1,
+              },
+            },
+          },
+        ],
+      };
 
-				option && myChart.setOption(option);
-			},
-			ChangeColors() {
-				this.colors = ["#aa2116", "#fcaf17"]
-			},
-			ChangeColor() {
-				this.colors = ["rgba(75, 85, 174, 1)", "rgba(05, 187, 76, 1)"]
-			},
-			closed() {
-				clearInterval(this.timer);
-				//勿删,传递关闭方法
-			},
-			// initData(PowerSet, ActualPower) {
-			// 	// this.chartData.units = ["(MW)", "(MW)"];
-			// 	this.chartData.value[0] = {
-			// 		title: "有功设定限值(MW)",
-			// 		yAxisIndex: 0,
-			// 		value: []
-			// 	};
-			// 	this.chartData.value[1] = {
-			// 		title: "实发有功(MW)",
-			// 		yAxisIndex: 0,
-			// 		value: []
-			// 	}
-			// 	PowerSet.forEach(item => {
-			// 		this.chartData.value[0].value.push({
-			// 			text: dayjs(item.ts).format('hh:mm'),
-			// 			value: parseFloat((item.doubleValue).toFixed(2))
-			// 		})
-			// 	})
-			// 	ActualPower.forEach(item => {
-			// 		this.chartData.value[1].value.push({
-			// 			text: dayjs(item.ts).format('hh:mm'),
-			// 			value: parseFloat((item.doubleValue).toFixed(2))
-			// 		})
-			// 	})
-			// 	this.powerLineChartData = this.chartData;
-			// }
-		},
-	};
+      option && myChart.setOption(option);
+    },
+    ChangeColors() {
+      this.colors = ["#aa2116", "#fcaf17"];
+    },
+    ChangeColor() {
+      this.colors = ["rgba(75, 85, 174, 1)", "rgba(05, 187, 76, 1)"];
+    },
+    closed() {
+      clearInterval(this.timer);
+      //勿删,传递关闭方法
+      clearInterval(this.intervals);
+      this.intervals = null;
+      this.timer = null;
+    },
+  },
+  unmounted() {
+    clearInterval(this.intervals);
+    this.intervals = null;
+  },
+};
 </script>
 <style scoped>
-	.echartsBox {
-		width: 64rem;
-		height: 220px;
-		overflow: hidden;
-	}
+.echartsBox {
+  width: 64rem;
+  height: 220px;
+  overflow: hidden;
+}
 
-	.el-dialog__header {
-		background-color: #000000;
-	}
+.el-dialog__header {
+  background-color: #000000;
+}
 
-	.showTitle {
-		display: flex;
-		flex-direction: row;
-		align-items: center;
-		justify-content: center;
-		margin-top: -10px;
-		font-size: 18px;
-		color: #FFFFFF;
-	}
+.showTitle {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  margin-top: -10px;
+  font-size: 18px;
+  color: #ffffff;
+}
 
-	.titleImg {
-		width: 16px;
-		height: 16px;
-		margin-right: 13px;
-	}
+.titleImg {
+  width: 16px;
+  height: 16px;
+  margin-right: 13px;
+}
 
-	.icon {
-		font-size: 12px;
-		margin-left: 10px;
-		margin-top: 5px;
-	}
+.icon {
+  font-size: 12px;
+  margin-left: 10px;
+  margin-top: 5px;
+}
 
-	.body {
-		background-color: black;
-		width: 100%;
-		margin-top: -30px;
-		/* height: 200px; */
-	}
+.body {
+  background-color: black;
+  width: 100%;
+  margin-top: -30px;
+  /* height: 200px; */
+}
 
-	.dataList {
-		display: flex;
-		flex-direction: row;
-		flex-wrap: wrap;
-		align-items: center;
-		padding-top: 27px;
-	}
+.dataList {
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  align-items: center;
+  padding-top: 27px;
+}
 
-	.data {
-		width: 50%;
-		display: flex;
-		flex-direction: row;
-		align-items: center;
-		margin-bottom: 22px;
-	}
+.data {
+  width: 50%;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-bottom: 22px;
+}
 
-	.name {
-		width: 40%;
-		display: flex;
-		flex-direction: row-reverse;
-		font-size: 12px;
-		color: #FFFFFF;
-	}
+.name {
+  width: 40%;
+  display: flex;
+  flex-direction: row-reverse;
+  font-size: 12px;
+  color: #ffffff;
+}
 
-	.num {
-		margin-left: 59px;
-		font-size: 16px;
-		color: #05BB4C;
-		min-width: 40px;
-	}
+.num {
+  margin-left: 59px;
+  font-size: 16px;
+  color: #05bb4c;
+  min-width: 40px;
+}
 
-	.unit {
-		font-size: 16px;
-		color: #FFFFFF;
-		margin-left: 20px;
-	}
+.unit {
+  font-size: 16px;
+  color: #ffffff;
+  margin-left: 20px;
+}
 
-	.condition {
-		width: 100%;
-		display: flex;
-		flex-direction: row;
-		align-items: center;
-		margin-bottom: 20px;
-		border-bottom: 1px solid #3D3D3D;
-		padding-bottom: 10px;
-	}
+.condition {
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  margin-bottom: 20px;
+  border-bottom: 1px solid #3d3d3d;
+  padding-bottom: 10px;
+}
 
-	.status {
-		width: 25%;
-		display: flex;
-		flex-direction: row;
-		align-items: center;
-		justify-content: center;
-	}
+.status {
+  width: 25%;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+}
 
-	.statusIcon {
-		width: 14px;
-		height: 14px;
-		margin-left: 8px;
-	}
+.statusIcon {
+  width: 14px;
+  height: 14px;
+  margin-left: 8px;
+}
 
-	.echarts {
-		width: 100%;
-		height: 400px;
-		display: inline-block;
-	}
+.echarts {
+  width: 100%;
+  height: 400px;
+  display: inline-block;
+}
 </style>

Diferenças do arquivo suprimidas por serem muito extensas
+ 731 - 549
src/components/modeControl/modeControl.vue


+ 93 - 0
src/components/panel/panel-no-title.vue

@@ -0,0 +1,93 @@
+<template>
+  <div class="com-panel" :class="{ 'no-title': !hasTitle }">
+    <div v-if="hasTitle" class="panel-header">
+      <div class="panel-title">
+        <i v-if="hasIcon" class="panel-icon" :class="icon"></i>
+        {{ title }}
+      </div>
+      <div class="panel-tools">{{ subTitle }}</div>
+    </div>
+    <div class="panel-body">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "com-panel",
+  componentName: "com-panel",
+  props: {
+    title: String,
+    icon: String,
+    subTitle: String,
+  },
+  computed: {
+    hasTitle() {
+      if (this.title) return true;
+      return false;
+    },
+    hasIcon() {
+      if (this.icon) return true;
+      return false;
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+.com-panel {
+  border-left: 0.185vh solid rgba(255, 255, 255, 50%);
+
+  &:before {
+    content: " ";
+    width: 0.37vh;
+    height: 0.37vh;
+    float: left;
+    background: #fff;
+    margin: 0.185vh 0.556vh 0vh 0.185vh;
+  }
+
+  &.no-title {
+    border-left: 0vh;
+  }
+
+  &.no-title::before {
+    display: none;
+  }
+
+  .panel-header {
+    display: flex;
+    font-size: @fontsize;
+    padding-left: 1.4815vh;
+    background: rgba(255, 255, 255, 10%);
+    line-height: 2.963vh;
+    margin-bottom: 1.481vh;
+
+    .panel-title {
+      color: rgba(255, 255, 255, 0.8);
+      flex: 1 1 auto;
+      .panel-icon {
+        margin-right: 0.741vh;
+      }
+    }
+
+    .panel-tools {
+      flex: 0 0 auto;
+      color: #fff;
+      opacity: 0.3;
+      padding: 0 0.741vh;
+      font-size: @fontsize-s;
+      letter-spacing: 0.093vh;
+    }
+  }
+
+  .panel-body {
+    padding-left: 1.111vh;
+    color: rgba(255, 255, 255, 0.8);
+  }
+
+  &.no-title .panel-body {
+    padding-left: 0vh;
+  }
+}
+</style>

+ 73 - 0
src/components/panel/panel-sand-toolbar.vue

@@ -0,0 +1,73 @@
+<template>
+    <div class="com-panel-sand">
+        <div class="com-panel-sand-header font-sm white">
+            {{ title }}<div class="com-panel-sand-sub-title"><slot name="tools"></slot></div>
+        </div>
+        <div class="com-panel-body">
+            <slot></slot>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: "com-panel-sand-toolbar",
+    componentName: "com-panel-sand-toolbar",
+    props: {
+        // 标题
+        title: {
+            type: String,
+            default: "",
+        },
+    },
+};
+</script>
+<style lang="less">
+.com-panel-sand {
+    background: #1a1f2fCC;
+    padding: 0 1.481vh 1.481vh 1.481vh;
+    border-top: 1px solid #15a952;
+    position: relative;
+
+    &::after {
+        content: "";
+        position: absolute;
+        width: 5px;
+        height: 5px;
+        background: #15a952;
+        right: -2.5px;
+        top: -2.5px;
+    }
+
+    .com-panel-sand-header {
+        text-align: center;
+        position: relative;
+        padding: 0.833vh 0;
+        border-bottom: 1px solid #15a95266;
+
+        &::after,
+        &::before {
+            content: "";
+            position: absolute;
+            bottom: -1px;
+            width: 15px;
+            height: 1px;
+            background: #15a952;
+        }
+
+        &::after {
+            left: 0;
+        }
+
+        &::before {
+            right: 0;
+        }
+
+        .com-panel-sand-sub-title {
+            position: absolute;
+            right: 0;
+            top: 0.833vh;
+        }
+    }
+}
+</style>

+ 78 - 0
src/components/panel/panel-sand.vue

@@ -0,0 +1,78 @@
+<template>
+    <div class="com-panel-sand">
+        <div class="com-panel-sand-header font-sm white">
+            {{ title }}<span class="com-panel-sand-sub-title font-sm gray">{{ subTitle }}</span>
+        </div>
+        <div class="com-panel-body">
+            <slot></slot>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: "com-panel-sand",
+    componentName: "com-panel-sand",
+    props: {
+        // 标题
+        title: {
+            type: String,
+            default: "",
+        },
+        // 副标题
+        subTitle: {
+            type: String,
+            default: "",
+        },
+    },
+};
+</script>
+<style lang="less">
+.com-panel-sand {
+    background: #1a1f2fCC;
+    padding: 0 1.481vh 1.481vh 1.481vh;
+    border-top: 1px solid #15a952;
+    position: relative;
+
+    &::after {
+        content: "";
+        position: absolute;
+        width: 5px;
+        height: 5px;
+        background: #15a952;
+        right: -2.5px;
+        top: -2.5px;
+    }
+
+    .com-panel-sand-header {
+        text-align: center;
+        position: relative;
+        padding: 0.833vh 0;
+        border-bottom: 1px solid #15a95266;
+
+        &::after,
+        &::before {
+            content: "";
+            position: absolute;
+            bottom: -1px;
+            width: 15px;
+            height: 1px;
+            background: #15a952;
+        }
+
+        &::after {
+            left: 0;
+        }
+
+        &::before {
+            right: 0;
+        }
+
+        .com-panel-sand-sub-title {
+            position: absolute;
+            right: 0;
+            top: 0.833vh;
+        }
+    }
+}
+</style>

+ 112 - 0
src/components/panel/panel.vue

@@ -0,0 +1,112 @@
+<template>
+  <div class="com-panel" :class="{ 'no-title': !hasTitle, line: showLine }">
+    <div v-if="hasTitle" class="panel-header">
+      <div class="panel-title">
+        <i v-if="hasIcon" class="panel-icon" :class="icon"></i>
+        {{ title }}
+      </div>
+      <div class="panel-tools">{{ subTitle }}</div>
+    </div>
+    <div class="panel-body" :class="{ blur: bgBlur }">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "com-panel",
+  componentName: "com-panel",
+  props: {
+    // 标题
+    title: String,
+    // 图标
+    icon: String,
+    // 副标题
+    subTitle: String,
+    showLine: {
+      type: Boolean,
+      default: true,
+    },
+    bgBlur: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  computed: {
+    // 是否存在标题
+    // 标题为空时 不显示标题框
+    hasTitle() {
+      if (this.title) return true;
+      return false;
+    },
+    // 是否存在图标
+    hasIcon() {
+      if (this.icon) return true;
+      return false;
+    },
+  },
+};
+</script>
+<style lang="less">
+.com-panel {
+  &.line {
+    border-left: 1px solid @gray;
+  }
+
+  &.line:before {
+    content: " ";
+    width: 3px;
+    height: 3px;
+    float: left;
+    background: #c9c9c9;
+    margin: 0.185vh 0.556vh 0vh 0.185vh;
+  }
+
+  &.no-title {
+    border-left: 0vh;
+  }
+
+  &.no-title::before {
+    display: none;
+  }
+
+  .panel-header {
+    display: flex;
+    font-size: 14px;
+    padding-left: 1.185vh;
+    background: rgba(255, 255, 255, 10%);
+    line-height: 27px;
+    margin-bottom: 0.7407vh;
+    height: 27px;
+
+    .panel-title {
+      color: fade(#fff, 75);
+      flex: 1 1 auto;
+      .panel-icon {
+        margin-right: 0.741vh;
+      }
+    }
+
+    .panel-tools {
+      flex: 0 0 auto;
+      color: #ffffff4d;
+      padding: 0 0.741vh;
+      font-size: 12px;
+      letter-spacing: 0.093vh;
+    }
+  }
+
+  .panel-body {
+    position: relative;
+  }
+
+  &.line .panel-body {
+    padding-left: 1.185vh;
+  }
+
+  &.no-title .panel-body {
+    padding-left: 0vh;
+  }
+}
+</style>

+ 139 - 0
src/components/panel/panel2.vue

@@ -0,0 +1,139 @@
+<template>
+  <div class="com-panel2" :class="(hasTitle ? '' : 'no-title') + ' ' + color">
+    <div v-if="hasTitle" class="panel-header2">
+      <div class="panel-title2">
+        <i v-if="hasIcon" class="panel-icon2" :class="icon"></i>
+        {{ title }}
+      </div>
+      <div class="panel-tools2">{{ subTitle }}</div>
+    </div>
+    <div class="panel-body2">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "ComPanel",
+  componentName: "ComPanel",
+  props: {
+    title: String,
+    icon: String,
+    subTitle: String,
+    color: String,
+  },
+  computed: {
+    hasTitle() {
+      if (this.title) return true;
+      return false;
+    },
+    hasIcon() {
+      if (this.icon) return true;
+      return false;
+    },
+  },
+};
+</script>
+<style lang="less">
+.com-panel2 {
+  border-left: 0.185vh solid rgba(255, 255, 255, 50%);
+  padding-left: 1.185vh;
+  position: relative;
+
+  &:before,
+  &:after {
+    content: " ";
+    width: 0.37vh;
+    height: 0.37vh;
+    background: @write;
+    position: absolute;
+    left: 0.185vh;
+  }
+
+  &:before {
+    top: 0.185vh;
+  }
+
+  &:after {
+    bottom: 0.185vh;
+  }
+
+  &.no-title {
+    border-left: 0vh;
+  }
+
+  &.no-title::before {
+    display: none;
+  }
+
+  &.green {
+    .panel-header2 {
+      &::after {
+        background-image: @greenLinearRight;
+        width: 10%;
+      }
+      .panel-title2 {
+        .panel-icon2 {
+          color: @green;
+        }
+      }
+    }
+  }
+
+  &.red {
+    .panel-header2 {
+      &::after {
+        background-image: @redLinearRight;
+        width: 10%;
+      }
+      .panel-title2 {
+        .panel-icon2 {
+          color: @red;
+        }
+      }
+    }
+  }
+
+  .panel-header2 {
+    display: flex;
+    font-size: @fontsize;
+    padding-left: 1.185vh;
+    background: fade(@gray, 20);
+    line-height: 2.963vh;
+    margin-bottom: 1.111vh;
+    position: relative;
+
+    &::after {
+      content: "";
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 40vh;
+      height: 100%;
+    }
+
+    .panel-title2 {
+      color: @write;
+
+      .panel-icon2 {
+        margin-right: 0.741vh;
+      }
+    }
+
+    .panel-tools2 {
+      color: #fff;
+      opacity: 0.3;
+      padding: 0 0.741vh;
+    }
+  }
+
+  .panel-body2 {
+    color: rgba(255, 255, 255, 0.8);
+  }
+
+  &.no-title .panel-body2 {
+    padding-left: 0vh;
+  }
+}
+</style>

+ 52 - 0
src/components/panel/panel3.vue

@@ -0,0 +1,52 @@
+<template>
+  <div class="com-panel-3">
+    <span class="dot top-left"></span>
+    <span class="dot bottom-left"></span>
+    <span class="dot top-rignt"></span>
+    <span class="dot bottom-right"></span>
+    <slot></slot>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "com-panel-3",
+  componentName: "com-panel-3",
+};
+</script>
+<style lang="less" scoped>
+.com-panel-3 {
+  position: relative;
+  background: rgba(255, 255, 255, 0.1);
+  padding: 1.4815vh;
+  display: inline-block;
+  border: 0.093vh solid #536268;
+
+  .dot {
+    position: absolute;
+    width: 0.370vh;
+    height: 0.370vh;
+    background: #fff;
+
+    &.top-left {
+      top: 0.556vh;
+      left: 0.556vh;
+    }
+
+    &.bottom-left {
+      bottom: 0.556vh;
+      left: 0.556vh;
+    }
+
+    &.top-rignt {
+      top: 0.556vh;
+      right: 0.556vh;
+    }
+
+    &.bottom-right {
+      bottom: 0.556vh;
+      right: 0.556vh;
+    }
+  }
+}
+</style>

+ 46 - 0
src/components/panel/toolbar-panel.vue

@@ -0,0 +1,46 @@
+<template>
+  <div class="com-panel" :class="{ 'no-title': !hasTitle, line: showLine }">
+    <div v-if="hasTitle" class="panel-header">
+      <div class="panel-title">
+        <i v-if="hasIcon" class="panel-icon" :class="icon"></i>
+        {{ title }}
+      </div>
+      <div class="panel-tools">
+        <slot name="tools"></slot>
+      </div>
+    </div>
+    <div class="panel-body">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script>
+// 副标题可嵌入html的panel
+export default {
+  name: "toolbar-panel",
+  componentName: "toolbar-panel",
+  props: {
+    // 标题
+    title: String,
+    // 图标
+    icon: String,
+    showLine: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  computed: {
+    hasTitle() {
+      if (this.title) return true;
+      return false;
+    },
+    hasIcon() {
+      if (this.icon) return true;
+      return false;
+    },
+  },
+};
+</script>
+
+<style lang="less"></style>

+ 2 - 1
src/components/problem/ProblemArea.vue

@@ -34,6 +34,7 @@
 </script>
 <style scoped>
   .problem {
-    height: 100%;
+    height: 97%;
+    background-color: #000000;
   }
 </style>

+ 309 - 126
src/components/problem/areaCard.vue

@@ -1,64 +1,123 @@
 /* 自定义tabs */
 <template>
-  <div class="body" :style="style">
-    <img class="logo" src="../../assets/img/logo.png" alt="" />
-    <div class="title">{{ title }}</div>
-    <div style="margin-top: 50px; height: 94%" @contextmenu="contextmenu">
-      <div class="scoll currentScroll">
-        <div class="currentScroll" style="height: 100%; overflow-y: scroll">
-          <div class="matrix" v-if="faultList.length > 0">
-            <div class="problemTitle">故障</div>
+  <div>
+    <div class="body" :style="style">
+      <img class="logo" src="../../assets/img/logo.png" alt="" />
+      <div class="Title">{{ title }}</div>
+      <div class="content" @contextmenu="contextmenu">
+        <!-- <el-scrollbar>
+        <div class="scoll"> -->
+        <el-collapse v-model="activeNames">
+          <el-collapse-item name="1">
+            <template v-slot:title>
+              <div class="tit1">
+                <div class="title">状态异常</div>
+                <span class="num">{{ statusRepair.length }}</span>
+              </div>
+            </template>
+            <MatrixBlock
+              area="problem"
+              @problem-click="handleClick"
+              @on-click="handleDetails"
+              :dataList="statusRepair"
+            ></MatrixBlock>
+          </el-collapse-item>
+          <el-collapse-item name="2">
+            <template v-slot:title>
+              <div class="tit1">
+                <div class="title">故障</div>
+                <span class="num">{{ faultList.length }}</span>
+              </div>
+            </template>
             <MatrixBlock
               area="problem"
               @problem-click="handleClick"
               @on-click="handleDetails"
               :dataList="faultList"
             ></MatrixBlock>
-          </div>
-          <div class="matrix" v-if="maintainList.length > 0">
-            <div class="problemTitle">维护</div>
+          </el-collapse-item>
+
+          <el-collapse-item name="3">
+            <template v-slot:title>
+              <div class="tit1">
+                <div class="title">维护</div>
+                <span class="num">{{ maintainList.length }}</span>
+              </div>
+            </template>
             <MatrixBlock
               area="problem"
               @problem-click="handleClick"
               @on-click="handleDetails"
               :dataList="maintainList"
             ></MatrixBlock>
-          </div>
-          <div class="matrix" v-if="offlineList.length > 0">
-            <div class="problemTitle">离线</div>
+          </el-collapse-item>
+
+          <el-collapse-item name="4">
+            <template v-slot:title>
+              <div class="tit1">
+                <div class="title">离线</div>
+                <span class="num">{{ offlineList.length }}</span>
+              </div>
+            </template>
             <MatrixBlock
               area="problem"
               @problem-click="handleClick"
               @on-click="handleDetails"
               :dataList="offlineList"
             ></MatrixBlock>
-          </div>
-          <div class="matrix" v-if="listedList.length > 0">
-            <div class="problemTitle">挂牌</div>
+          </el-collapse-item>
+
+          <el-collapse-item name="5">
+            <template v-slot:title>
+              <div class="tit1">
+                <div class="title">挂牌</div>
+                <span class="num">{{ listedList.length }}</span>
+              </div>
+            </template>
             <MatrixBlock
               area="problem"
               @problem-click="handleClick"
               @on-click="handleDetails"
               :dataList="listedList"
             ></MatrixBlock>
-          </div>
-        </div>
+          </el-collapse-item>
+
+          <el-collapse-item name="6">
+            <template v-slot:title>
+              <div class="tit1">
+                <div class="title">风速功率不匹配</div>
+                <span class="num">{{ unpaidList.length }}</span>
+              </div>
+            </template>
+            <MatrixBlock
+              area="problem"
+              @problem-click="handleClick"
+              @on-click="handleDetails"
+              :dataList="unpaidList"
+            ></MatrixBlock>
+          </el-collapse-item>
+        </el-collapse>
+
+        <!-- </div>
+      </el-scrollbar> -->
       </div>
     </div>
+    <WindturbineDetailPages
+      v-model="dialogVisible"
+      :showSvg="showSvg"
+      @close="handleClose"
+      :windturbine="currentWindturbine"
+    ></WindturbineDetailPages>
   </div>
-  <WindturbineDetailPages
-    v-model="dialogVisible"
-    :showSvg="showSvg"
-    @close="handleClose"
-    :windturbine="currentWindturbine"
-  ></WindturbineDetailPages>
 </template>
 
 <script>
 import BackgroundData from "utils/BackgroundData";
+import MessageBridge from "utils/MessageBridge";
 import WindturbineDetailPages from "../WindturbineDetailPages.vue";
 import MatrixBlock from "../matrixBlock.vue";
 import api from "api/index";
+import { debounce } from "lodash";
 export default {
   name: "gy-card",
   components: {
@@ -79,6 +138,7 @@ export default {
   },
   data() {
     return {
+      activeNames: ["1", "2", "3", "4", "5", "6"],
       dialogVisible: false,
       currentWindturbine: {},
       values: [],
@@ -87,33 +147,14 @@ export default {
       big: false,
       current: 0,
       faultList: [],
+      statusRepair: [],
+      unpaidList: [],
       maintainList: [],
       offlineList: [],
       listedList: [],
       chooseList: [],
-      titleList: [
-        {
-          id: 0,
-          title: "麻黄山",
-        },
-        {
-          id: 1,
-          title: "牛首山",
-        },
-        {
-          id: 2,
-          title: "青山",
-        },
-        {
-          id: 3,
-          title: "石板泉",
-        },
-        {
-          id: 4,
-          title: "香山",
-        },
-      ],
       currentWindturbine: {},
+      windturbineList: {},
       showSvg: false,
       controlErorCodes: [
         "控制成功",
@@ -139,19 +180,107 @@ export default {
     style() {
       return `width: 100%; height: ${this.height}vh;`;
     },
+    // windturbineChangeCount() {
+    //   return this.$store.state.changeCount;
+    // },
+    // windturbinelistComp() {
+    //   return this.$store.state.windturbinelist;
+    // },
   },
   created() {
     this.deal();
     this.getLocks();
+    // this.initData()
+    this.windturbineMessage();
+    this.intervals = setInterval(this.windturbineMessage, 3000);
   },
   methods: {
+    // initData: function () {
+    //   let mb = MessageBridge.getInstance();
+    //   let windturbine = [
+    //     { key: "/topic/windturbine", action: this.debounceWindturbineMessage },
+    //   ];
+    //   mb.register(windturbine);
+    // },
+    // debounceWindturbineMessage: debounce(function (msg) {
+    //   this.windturbineMessage(msg);
+    // }, 1000),
+    windturbineMessage() {
+      api.getWindturbine().then(res =>{
+        this.windturbineList = res.data
+        let json = res.data;
+      this.maintainList = [];
+        this.offlineList = [];
+        this.listedList = [];
+        this.faultList = [];
+        this.statusRepair = []
+        this.unpaidList = [];
+        let faultRecord = [];
+        let flashingList = this.$store.state.faultList || [];
+        let arr = Object.keys(json).sort();
+        for (let id of arr) {
+          let val = json[id];
+          this.chooseList.forEach((item) => {
+            if (item.windturbineId === val.windturbineId) {
+              val.active = true;
+            }
+          });
+          if (val.status === 5) {
+            let obj = flashingList.find(
+              (fs) => fs.windturbineId === val.windturbineId
+            );
+            if (obj) {
+              val.flashing = obj.flashing ? true : obj.flashing;
+            } else {
+              val.flashing = true;
+            }
+          }
+
+          if (val.lockValue === 9) {
+            val.lockValues = this.lockValues.filter(
+              (item) => val.windturbineId === item.windturbineID
+            )[0]?.value;
+          }
+          if(val.abnormalState === true) {
+            this.statusRepair.push(val)
+          }
+          switch (val.status) {
+            case 4:
+              if (val.undeliveredStatus >= 4) {
+                this.unpaidList.push(val);
+              }
+              break;
+            case 5:
+              faultRecord.push(val);
+              this.faultList.push(val);
+              break;
+            case 6:
+              this.maintainList.push(val);
+              break;
+            case 7:
+              this.offlineList.push(val);
+              break;
+          }
+          if (val.lockValue > 0) {
+            this.listedList.push(val);
+          }
+        }
+        this.$store.commit("faultList", faultRecord);
+      })
+      
+    },
     deal() {
-      let json = this.$store.state.windturbinelist;
+      let json = this.windturbineList;
+      console.log(json);
+      this.unpaidList = [];
       this.faultList = [];
       this.maintainList = [];
+      this.statusRepair = []
       this.offlineList = [];
       this.listedList = [];
+
       let arr = Object.keys(json).sort();
+
       for (let id of arr) {
         let val = json[id];
         this.chooseList.forEach((item) => {
@@ -159,7 +288,15 @@ export default {
             val.active = true;
           }
         });
+        if(val.abnormalState === true){
+          this.statusRepair.push(val)
+        }
         switch (val.status) {
+          case 4:
+            if (val.undeliveredStatus >= 4) {
+              this.unpaidList.push(val);
+            }
+            break;
           case 5:
             this.faultList.push(val);
             break;
@@ -183,6 +320,12 @@ export default {
       });
     },
     handleClick(values) {
+      let flashingList = this.$store.state.faultList;
+      if (values.flashing) {
+        flashingList.filter(
+          (item) => values.windturbineId === item.windturbineId
+        )[0].flashing = false;
+      }
       if (values.active) {
         let showIndex = null;
         this.chooseList.forEach((item, index) => {
@@ -200,6 +343,11 @@ export default {
           (item.active = !item.active), (flag = true);
         }
       });
+      this.statusRepair.forEach((item) => {
+        if (item.windturbineId === values.windturbineId) {
+          (item.active = !item.active), (flag = true);
+        }
+      });
       flag
         ? ""
         : this.maintainList.forEach((item) => {
@@ -221,6 +369,13 @@ export default {
               item.active = !item.active;
             }
           });
+      flag
+        ? ""
+        : this.unpaidList.forEach((item) => {
+            if (item.windturbineId === values.windturbineId) {
+              item.active = !item.active;
+            }
+          });
     },
     /* 右键菜单 */
     contextmenu() {
@@ -342,9 +497,9 @@ export default {
       }
       let tp = iserror ? "success" : "warning";
       let dt = iserror ? 0 : 4500;
-      if (!iserror) {
-        mss = "控制成功";
-      }
+      // if (!iserror) {
+      //   mss = "控制成功";
+      // }
 
       this.$notify({
         title: "控制",
@@ -367,39 +522,10 @@ export default {
         duration: 3000,
       });
     },
-    filter(value, windturbineId) {
-      let array = [];
-      let flag = false;
-      for (let i = 0; i < value.length; i++) {
-        if (value[i].windturbineId == windturbineId) {
-          flag = true;
-          array.push(flag); // 风机是否已经存在
-          array.push(i); // 风机在values数组的位置
-          array.push(value[i].active); // 当前风机是否被选中
-          break;
-        }
-      }
-      return array;
-    },
     changeTitle(id) {
       this.current = id;
       this.$refs.malfunction.dateClick(id);
     },
-    addCard(val) {
-      let active = false;
-      let array = this.filter(this.values, val.windturbineId);
-      if (!array[0]) {
-        // 维护
-        val.active = active;
-        if (val.modelId.indexOf("105") >= 0) {
-          val.rollSpeed *= 9.55;
-        }
-        this.values.push(val);
-      } else {
-        val.active = array[2];
-        this.values.splice(array[1], 1, val);
-      }
-    },
     handleDetails(itm) {
       this.dialogVisible = true;
       this.currentWindturbine = itm;
@@ -410,49 +536,79 @@ export default {
       this.getLocks();
     },
   },
+  unmounted() {
+    clearInterval(this.intervals);
+    this.intervals = null;
+  },
   watch: {
-    "$store.getters.windturbinelist": {
-      deep: true,
-      handler: function (json) {
-        this.faultList = [];
-        this.maintainList = [];
-        this.offlineList = [];
-        this.listedList = [];
-        let arr = Object.keys(json).sort();
-        for (let id of arr) {
-          let val = json[id];
-          this.chooseList.forEach((item) => {
-            if (item.windturbineId === val.windturbineId) {
-              val.active = true;
-            }
-          });
-          if (val.lockValue === 9) {
-            val.lockValues = this.lockValues.filter(
-              (item) => val.windturbineId === item.windturbineID
-            )[0]?.value;
-          }
-          switch (val.status) {
-            case 5:
-              this.faultList.push(val);
-              break;
-            case 6:
-              this.maintainList.push(val);
-              break;
-            case 7:
-              this.offlineList.push(val);
-              break;
-          }
-          if (val.lockValue > 0) {
-            this.listedList.push(val);
-          }
-        }
-      },
-    },
+    // windturbineChangeCount(val) {
+    //   if (val > 0) {
+    //     this.maintainList = [];
+    //     this.offlineList = [];
+    //     this.listedList = [];
+    //     this.faultList = [];
+    //     this.unpaidList = [];
+    //     let faultRecord = [];
+    //     let flashingList = this.$store.state.faultList || [];
+    //     let arr = Object.keys(this.windturbinelistComp).sort();
+    //     for (let id of arr) {
+    //       let val = this.windturbinelistComp[id];
+    //       this.chooseList.forEach((item) => {
+    //         if (item.windturbineId === val.windturbineId) {
+    //           val.active = true;
+    //         }
+    //       });
+    //       if (val.status === 5) {
+    //         let obj = flashingList.find(
+    //           (fs) => fs.windturbineId === val.windturbineId
+    //         );
+    //         if (obj) {
+    //           val.flashing = obj.flashing ? true : obj.flashing;
+    //         } else {
+    //           val.flashing = true;
+    //         }
+    //       }
+
+    //       if (val.lockValue === 9) {
+    //         val.lockValues = this.lockValues.filter(
+    //           (item) => val.windturbineId === item.windturbineID
+    //         )[0]?.value;
+    //       }
+    //       switch (val.status) {
+    //         case 4:
+    //           if (val.undeliveredStatus >= 3) {
+    //             this.unpaidList.push(val);
+    //           }
+    //           break;
+    //         case 5:
+    //           faultRecord.push(val);
+    //           this.faultList.push(val);
+    //           break;
+    //         case 6:
+    //           this.maintainList.push(val);
+    //           break;
+    //         case 7:
+    //           this.offlineList.push(val);
+    //           break;
+    //       }
+    //       if (val.lockValue > 0) {
+    //         this.listedList.push(val);
+    //       }
+    //     }
+    //     this.$store.commit("faultList", faultRecord);
+    //   }
+    // },
   },
 };
 </script>
 
 <style scoped="scoped">
+.tit1 {
+  width: 92%;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
 .body {
   border: 1px solid #373737;
   width: 100%;
@@ -462,13 +618,13 @@ export default {
 
 .body .scoll {
   height: 91%;
-  overflow-y: scroll;
 }
 
-.title {
+.Title {
   color: #ffffff;
   font-size: 14px;
   margin-left: 32px;
+  font-weight: bold;
   /* margin-top: 12px; */
   margin-bottom: 10px;
   /* width: 570px; */
@@ -480,7 +636,7 @@ export default {
   background-color: #000000;
 }
 
-.title::before {
+.Title::before {
   z-index: 1;
   content: "";
   position: absolute;
@@ -491,6 +647,15 @@ export default {
   background-color: #54b75a;
   border-radius: 50%;
 }
+.content {
+  overflow-y: auto;
+  margin-top: 50px;
+  height: 94%;
+}
+.content::-webkit-scrollbar {
+  /*隐藏滚轮*/
+  display: none;
+}
 
 .logo {
   position: absolute;
@@ -506,10 +671,28 @@ export default {
 }
 
 .problemTitle {
-  font-size: 12px;
-  color: #bfbfbf;
-  margin-top: 20px;
-  margin-bottom: 20px;
-  margin-left: 12px;
+  /* box-sizing: border-box; */
+  /* padding-left: 20px; */
+}
+</style>
+
+<style lang="less">
+.tit1{
+    .title{
+        font-size: 14px;
+        font-weight: bold;
+        color: #bfbfbf;
+    }
+    .num {
+        color: #fff;
+        display: inline-block;
+        width: 30px;
+        height: 30px;
+        background-color: rgba(37, 116, 219, 1);
+        border-radius: 50%;
+        line-height: 30px;
+        text-align: center;
+        box-sizing: border-box;
+    }
 }
-</style>
+</style>

+ 868 - 0
src/components/search/action.vue

@@ -0,0 +1,868 @@
+<template>
+  <el-dialog
+    width="70%"
+    @open="opened"
+    @closed="closed"
+    :fullscreen="true"
+    :show-close="true"
+    class="dialogs"
+  >
+    <template #title>
+      <div class="showTitles currentShowTitles">
+        <div class="titles">动作查询</div>
+      </div>
+    </template>
+    <div class="body">
+      <div class="bodyDetial">
+        <!-- <div style="width: 50%;height:200px;background-color:red;"></div>
+      <div style="width: 50%;height:200px;background-color:yellow;"></div> -->
+        <div class="left-item">
+          <el-scrollbar>
+            <el-input placeholder="输入关键字进行过滤" v-model="filterText">
+            </el-input>
+            <el-tree
+              class="filter-tree"
+              :data="showData"
+              :props="defaultProps"
+              :filter-node-method="filterNode"
+              node-key="id"
+              :default-expanded-keys="[0]"
+              ref="tree"
+              @node-click="handleChange"
+            >
+            </el-tree>
+          </el-scrollbar>
+        </div>
+        <div class="right-item">
+          <div class="dateBar">
+            <el-date-picker
+              class="pickers"
+              @change="changes"
+              v-model="timeValue"
+              type="datetimerange"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+            >
+            </el-date-picker>
+            <div
+              class="buttons"
+              @click="
+                () => {
+                  getControlRecord();
+                  getControlStatistics();
+                }
+              "
+            >
+              查询
+            </div>
+          </div>
+          <el-scrollbar style="height: 94%">
+            <div class="tables">
+              <el-table
+                :data="recordData"
+                class="table"
+                style="width: 100%"
+                height="81vh"
+                :header-cell-style="{
+                  background: 'rgb(30,30,30)',
+                  color: 'rgb(220,220,220)',
+                  padding: '4px',
+                  fontSize: '14px',
+                  'border-bottom': 'solid 1px rgba(77, 77, 77, 1)',
+                }"
+                :cell-style="{
+                  height: '40px',
+                  background: 'rgb(30,30,30)',
+                  color: 'rgb(220,220,220)',
+                  padding: '3px',
+                  fontSize: '12px',
+                  'border-bottom': '1px solid #000000',
+                }"
+                @cell-dblclick="cellDbClick"
+              >
+                <el-table-column
+                  prop="time"
+                  label="日期"
+                  width="120"
+                  align="center"
+                >
+                </el-table-column>
+                <el-table-column
+                  prop="code"
+                  label="风机号"
+                  width="120"
+                  align="center"
+                >
+                </el-table-column>
+                <el-table-column
+                  prop="controls"
+                  label="控制命令"
+                  width="100"
+                  align="center"
+                >
+                </el-table-column>
+                <el-table-column prop="result" label="操作结果" align="center">
+                </el-table-column>
+                <el-table-column
+                  prop="userName"
+                  label="操作人"
+                  width="160"
+                  align="center"
+                >
+                </el-table-column>
+                 <el-table-column
+                  prop="windSpeed"
+                  label="风速(m/s)"
+                  width="160"
+                  align="center"
+                >
+                </el-table-column>
+                 <el-table-column
+                  prop="statusChanged"
+                  label="状态转换"
+                  width="160"
+                  align="center"
+                >
+                </el-table-column>
+                <el-table-column
+                  prop="statusChangeInterval"
+                  label="状态转换时间(s)"
+                  width="160"
+                  align="center"
+                >
+                </el-table-column>
+              </el-table>
+              <div class="titleinfoall" v-if="showControlStatistics">
+                <div class="titleinfo">
+                  <span class="showTitle fontSty1">启动:</span>
+                  <span class="showvalue">
+                   {{controlStatisticsInfo.startSuccessCount }}/{{ controlStatisticsInfo.startCount}}
+                  </span>
+                  <span class="showTitle fontSty">次</span>
+                </div>
+                <div class="titleinfo">
+                  <span class="showTitle fontSty1">停机:</span>
+                  <span class="showvalue">
+                    {{controlStatisticsInfo.stopSuccessCount}}/{{ controlStatisticsInfo.stopCount }}
+                  </span>
+                  <span class="showTitle fontSty">次</span>
+                </div>
+                <div class="titleinfo">
+                  <span class="showTitle fontSty1">维护:</span>
+                  <span class="showvalue">
+                    {{controlStatisticsInfo.maintenanceSuccessCount }}/{{ controlStatisticsInfo.maintenanceCount}}
+                  </span>
+                  <span class="showTitle fontSty">次</span>
+                </div>
+                <div class="titleinfo">
+                  <span class="showTitle fontSty1">解除维护:</span>
+                  <span class="showvalue">
+                    {{controlStatisticsInfo.unMaintenanceSuccessCount }}/{{ controlStatisticsInfo.unMaintenanceCount}}
+                  </span>
+                  <span class="showTitle fontSty">次</span>
+                </div>
+                <div class="titleinfo">
+                  <span class="showTitle fontSty1">多发电量:</span>
+                  <span class="showvalue">
+                    {{ controlStatisticsInfo.powerGeneration?.toFixed(2) || 0 }}
+                  </span>
+                  <span class="showTitle fontSty">kwh</span>
+                </div>
+                <div class="titleinfo">
+                  <span class="showTitle fontSty1">节约电量:</span>
+                  <span class="showvalue">
+                    {{ controlStatisticsInfo.powerSaving?.toFixed(2) || 0 }}
+                  </span>
+                  <span class="showTitle fontSty">kwh</span>
+                </div>
+                <div class="titleinfo">
+                  <span class="showTitle fontSty1">维护时长:</span>
+                  <span class="showvalue">
+                    {{ controlStatisticsInfo.maintenanceTime?.toFixed(2) || 0 }}
+                  </span>
+                  <span class="showTitle fontSty">分钟</span>
+                </div>
+                <div class="titleinfo">
+                  <span class="showTitle fontSty1">提前时间:</span>
+                  <span class="showvalue">
+                    {{ controlStatisticsInfo.advanceTime?.toFixed(2) || 0 }}
+                  </span>
+                  <span class="showTitle fontSty">分钟</span>
+                </div>
+              </div>
+            </div>
+          </el-scrollbar>
+          <div class="paginations">
+            <el-pagination
+              :hide-on-single-page="true"
+              :page-size="currentPage"
+              background
+              layout="prev, pager, next"
+              :total="total"
+              @current-change="handleCurrentChange"
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+    <el-dialog
+      class="dialogs"
+      custom-class="currentBorder"
+      width="70%"
+      top="50px"
+      :show-close="true"
+      append-to-body
+      v-model="showStartDialog"
+    >
+      <div id="chart" style="width: 100%; height: 500px" />
+      <el-card class="otherContentBox" v-if="otherContentInfo.success">
+        <el-descriptions title="控制评分">
+          <el-descriptions-item label="控制时间">{{
+            otherContentInfo.operationRecordTs || "---"
+          }}</el-descriptions-item>
+          <el-descriptions-item label="并网开始时间">{{
+            otherContentInfo.onLineStartTs || "---"
+          }}</el-descriptions-item>
+          <el-descriptions-item label="并网结束时间">{{
+            otherContentInfo.onLineEndTs || "---"
+          }}</el-descriptions-item>
+          <el-descriptions-item label="并网时长">
+            {{ otherContentInfo.onLineDuration || "---" }}
+          </el-descriptions-item>
+          <el-descriptions-item label="并网期间发电量">{{
+            otherContentInfo.onLinePowerGeneration
+          }}</el-descriptions-item>
+          <el-descriptions-item label="单位时间内发电量">{{
+            otherContentInfo.powerGenerationPerHour
+          }}</el-descriptions-item>
+          <el-descriptions-item label="并网期间耗电量">{{
+            otherContentInfo.powerConsumption
+          }}</el-descriptions-item>
+          <!-- <el-descriptions-item label="风能利用百分比">{{
+            otherContentInfo.windUseRate
+          }}</el-descriptions-item> -->
+          <el-descriptions-item label="评分">
+            <el-rate
+              style="display: inline-block"
+              v-model="otherContentInfo.score"
+              allow-half
+              disabled
+            />
+            <span>{{ otherContentInfo.score * 2 }}&nbsp;/&nbsp;10&nbsp;分</span>
+          </el-descriptions-item>
+        </el-descriptions>
+      </el-card>
+      <el-card class="otherContentBox" v-else>
+        <div
+          style="
+            width: 100%;
+            height: 140px;
+            color: #eee;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            font-size: 18px;
+          "
+        >
+          <el-empty
+            class="empSvg"
+            :image-size="100"
+            description="暂无控制评分"
+          />
+        </div>
+      </el-card>
+    </el-dialog>
+  </el-dialog>
+</template>
+
+<script>
+import dayjs from "dayjs";
+import api from "api/index";
+import * as echarts from "echarts";
+export default {
+  props: {},
+  updated() {
+    if (this.timeValue.length === 0) {
+      let date = new Date();
+      this.timeValue[0] = date.getTime() - 28800000;
+      this.timeValue[1] = date.getTime() + 3600000;
+    }
+  },
+  mounted() {},
+  data() {
+    return {
+      statname:"",
+      currentPage: 20,
+      filterText: "",
+      pageIndex: 1,
+      station: [],
+      datas: {},
+      chooseStation: {},
+      timeValue: [],
+      showData: [
+        {
+          id: 0,
+          code: "全部",
+          stationId: "",
+          children: [],
+        },
+      ],
+      defaultProps: {
+        children: "children",
+        label: "code",
+      },
+      recordData: [],
+      total: "",
+      controlErorCodes: [
+        "控制成功",
+        "控制命令发送失败",
+        "无效的控制地址",
+        "被控设备异常",
+        "无效的控制功能",
+        "网络连接错误,检查场站通信",
+        "控制结果读取超时",
+        "未知错误",
+        "控制命令错误",
+        "收到无法识别数据",
+        "未读取到数据包",
+        "未知错误",
+        "风机操作过频繁",
+        "风机被挂牌",
+        "风机操作与风机状态不符",
+        "需要登录",
+      ],
+      showStartDialog: false,
+      rateValue: 4.5,
+      otherContentInfo: {
+        score: 0,
+      },
+      showControlStatistics: false,
+      controlStatisticsInfo: {},
+    };
+  },
+  methods: {
+    // getWindturbineFdc() {
+    //   api.getWindturbineFdc().then((res) => {
+    //     this.station = res.data;
+    //     this.getControlRecord();
+    //   });
+    // },
+    dataDeal() {
+      let stationList = this.$store.state.stationList;
+      this.showData[0].children = [
+        // {
+        //   id : 1,
+        // code : "风机全部",
+        // stationId : "WIND_ALL",
+        // children : [],
+        // }
+      ];
+      stationList.forEach((item, index) => {
+        if (item.type === 1) {
+          let obj = {};
+          obj.id = index + 1;
+          obj.code = item.name;
+          obj.stationId = item.id;
+          obj.children = [];
+          this.showData[0].children.push(obj);
+          // console.log(123,obj.stationId);
+        }
+      });
+      this.datas = this.$store.state.windturbinelist
+        ? this.$store.state.windturbinelist
+        : {};
+      let arr = Object.keys(this.datas).sort();
+      for (let id of arr) {
+        let item = this.datas[id];
+        this.showData[0].children
+          .filter((val) => val.stationId === item.stationId)[0]
+          ?.children.push(item);
+      }
+    },
+    handleChange(value) {
+      // console.log(111,value);
+      this.statname=value.stationId
+      this.chooseStation = value;
+      this.pageIndex = 1;
+      this.getControlRecord(value);
+      this.getControlStatistics()
+    },
+    closed() {
+      this.pageIndex = 1;
+      this.chooseStation = {};
+      this.showData = [
+        {
+          id: 0,
+          code: "全部",
+          stationId: "",
+          children: [],
+        },
+      ];
+      let stationList = this.$store.state.stationList;
+      stationList.forEach((item, index) => {
+        let obj = {};
+        obj.id = index + 1;
+        obj.code = item.name;
+        obj.stationId = item.id;
+        obj.children = [];
+        this.showData[0].children.push(obj);
+      });
+
+      this.$emit("closed");
+    },
+    filterNode(value, data) {
+      if (!value) return true;
+      return data.code.indexOf(value) !== -1;
+    },
+    handleCurrentChange(val) {
+      this.pageIndex = val;
+      this.getControlRecord();
+    },
+    opened() {
+      let date = new Date();
+      this.timeValue[0] = date.getTime() - 28800000;
+      this.timeValue[1] = date.getTime() + 3600000;
+      this.dataDeal();
+      this.getControlRecord();
+    },
+
+    getControlStatistics() {
+      this.showControlStatistics = false;
+      this.controlStatisticsInfo = {};
+      const stTs = this.timeValue[0];
+      const endTs = this.timeValue[1];
+      const stationId=this.statname
+      api
+        .getControlStatistics(
+          new Date(stTs).getTime(),
+          new Date(endTs).getTime(),
+          stationId
+        )
+        .then((res) => {
+          this.showControlStatistics = true;
+          // console.log(999,res);
+          this.controlStatisticsInfo = {
+            advanceTime: res.data.advanceTime,
+            maintenanceCount: res.data.maintenanceCount,
+            maintenanceSuccessCount:res.data.maintenanceSuccessCount,
+            powerGeneration: res.data.powerGeneration,
+            powerSaving: res.data.powerSaving,
+            startCount: res.data.startCount,
+            startSuccessCount:res.data.startSuccessCount,
+            stopSuccessCount:res.data.stopSuccessCount,
+            stopCount: res.data.stopCount,
+            unMaintenanceCount: res.data.unMaintenanceCount,
+            unMaintenanceSuccessCount: res.data.unMaintenanceSuccessCount,
+            maintenanceTime: res.data.maintenanceTime,
+          };
+        });
+    },
+    getControlRecord() {
+      api
+        .controlRecord({
+          stationId: this.chooseStation.stationId
+            ? this.chooseStation.stationId
+            : "",
+          userName: "",
+          windturbineId:
+            String(this.chooseStation?.id)?.length < 2
+              ? ""
+              : this.chooseStation.stationId
+              ? this.chooseStation.windturbineId
+              : "",
+          startTime: dayjs(this.timeValue[0]).format("YYYY/MM/DD HH:mm:ss"),
+          endTime: dayjs(this.timeValue[1]).format("YYYY/MM/DD HH:mm:ss"),
+          pageSize: this.currentPage,
+          pageIndex: this.pageIndex,
+        })
+        .then((res) => {
+          console.log(123,res);
+          if (res) {
+            let types = {
+              Start: "启动",
+              Stop: "停止",
+              Reset: "复位",
+              Maintain: "维护",
+              UnMaintain: "取消维护",
+              Lock: "挂牌",
+              UnLock: "取消挂牌",
+            };
+            // console.log(666,res);
+            res.data.dataList.forEach((item) => {
+              item.time = dayjs(item.time).format("MM-DD HH:mm:ss");
+              item.result = this.controlErorCodes[item.errorCode];
+              item.controls = types[item.controlType];
+              item.showName = item.windturbineId;
+              item.windSpeed=item.windSpeed.toFixed(2)
+              if(item.statusChanged==false){
+                 item.statusChanged=''
+              }else{
+                item.statusChanged='成功'
+              }
+            });
+            this.total = res.data.total;
+            this.recordData = res.data.dataList;
+            console.log(666,res.data.dataList);
+          }
+        });
+    },
+
+    cellDbClick(row) {
+      const controlType = row.controlType || "";
+      if (controlType === "Start") {
+        this.initEcharts(row.id);
+      }
+    },
+
+    initEcharts(id) {
+      api.getEvaluationData(id).then((res) => {
+        var data = res.data.datas;
+        var statistics = res.data.statistics;
+        var marks = new Array();
+        if (Array.isArray(statistics.mark)) {
+          for (var j = 0; j < statistics.mark.length; ++j) {
+            marks.push({ xAxis: statistics.mark[j] });
+          }
+        }
+
+        var ser = new Array();
+        var isFirst = true;
+        for (var i = 0; i < data.length; ++i) {
+          var s = {
+            data: data[i].values.map((item) => {
+              return item.value;
+            }),
+            type: "line",
+            name: data[i].name,
+            symbol: "none",
+            yAxisIndex: /功率/g.test(data[i].name) ? 1 : 0,
+          };
+          if (isFirst) {
+            s.markLine = {
+              symbol: ["none", "none"],
+              label: { show: false },
+              data: marks,
+            };
+          }
+          ser.push(s);
+          isFirst = false;
+        }
+
+        var option = {
+          tooltip: {
+            trigger: "axis",
+          },
+          legend: {
+            show: true,
+            textStyle: {
+              color: "#eee", //字体颜色
+            },
+            data: data.map((item) => {
+              return item.name;
+            }),
+          },
+          xAxis: {
+            type: "category",
+            data: data[0].values.map((item) => {
+              return new Date(item.ts).toLocaleString();
+            }),
+            axisLabel: {
+              show: true,
+              textStyle: {
+                color: "#eee",
+              },
+            },
+          },
+          yAxis: [
+            {
+              type: "value",
+              name: "风速(m/s)",
+              nameTextStyle: {
+                color: "#fff",
+              },
+              axisLabel: {
+                textStyle: {
+                  color: "#eee",
+                },
+              },
+              splitLine: {
+                lineStyle: {
+                  color: ["#878787"],
+                },
+              },
+            },
+            {
+              type: "value",
+              name: "功率(kw)",
+              nameTextStyle: {
+                color: "#fff",
+              },
+              axisLabel: {
+                textStyle: {
+                  color: "#eee",
+                },
+              },
+              splitLine: {
+                show: false,
+              },
+            },
+          ],
+          dataZoom: [
+            {
+              type: "inside",
+              start: 0,
+              end: 100,
+            },
+          ],
+          series: ser,
+        };
+
+        if (res.data.statistics.success) {
+          this.otherContentInfo = {
+            operationRecordTs: this.formatDate(
+              new Date(res.data.statistics.allTime.operationRecordTs)
+            ),
+            onLineStartTs: this.formatDate(
+              new Date(res.data.statistics.allTime.onlineStartTs)
+            ),
+            onLineEndTs: this.formatDate(
+              new Date(res.data.statistics.allTime.onlineEndTs)
+            ),
+            onLineDuration: `${res.data.statistics.allTime.onLineDuration.toFixed(
+              2
+            )} h`,
+            onLinePowerGeneration: `${res.data.statistics.onLinePowerGeneration.toFixed(
+              2
+            )} kwh`,
+            powerGenerationPerHour: `${res.data.statistics.powerGenerationPerHour.toFixed(
+              2
+            )} kwh`,
+            powerConsumption: `${res.data.statistics.powerConsumption.toFixed(
+              2
+            )} kwh`,
+            windUseRate: `${res.data.statistics.windUseRate.toFixed(2)} %`,
+            score: res.data.statistics.score / 2,
+            success: res.data.statistics.success,
+          };
+        } else {
+          this.otherContentInfo = {};
+        }
+
+        this.showStartDialog = true;
+
+        this.$nextTick(() => {
+          let chartDom = document.getElementById("chart");
+          chartDom.innerHTML = "";
+          chartDom?.removeAttribute("_echarts_instance_");
+          let chart = echarts.init(chartDom, null, { renderer: "svg" });
+          chart.setOption(option);
+        });
+      });
+    },
+
+    formatDate(value) {
+      var date = new Date(value);
+      var y = date.getFullYear(),
+        m = date.getMonth() + 1,
+        d = date.getDate(),
+        h = date.getHours(),
+        i = date.getMinutes(),
+        s = date.getSeconds();
+      if (m < 10) {
+        m = "0" + m;
+      }
+      if (d < 10) {
+        d = "0" + d;
+      }
+      if (h < 10) {
+        h = "0" + h;
+      }
+      if (i < 10) {
+        i = "0" + i;
+      }
+      if (s < 10) {
+        s = "0" + s;
+      }
+      var t = y + "-" + m + "-" + d + " " + h + ":" + i + ":" + s;
+      return t;
+    },
+  },
+  watch: {
+    filterText(val) {
+      this.$refs.tree.filter(val);
+    },
+  },
+};
+</script>
+<style lang="less" scoped>
+.body {
+  background-color: #000000;
+  height: 90vh;
+  width: 102%;
+  margin-left: -1%;
+  margin-top: -40px;
+}
+.searchTitle {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+}
+.bodyDetial {
+  display: flex;
+  flex-direction: row;
+  margin-left: 3vw;
+  padding-top: 10px;
+  color: #ffffff;
+  height: 98%;
+}
+
+.left-item {
+  width: 20%;
+  height: 100%;
+  background-color: rgba(77, 77, 77, 1);
+  border-right: 2px solid #000000;
+}
+
+.right-item {
+  width: 80%;
+  height: 100%;
+  background-color: rgba(77, 77, 77, 1);
+}
+
+.el-tree {
+  color: #ffffff !important;
+  background-color: rgba(77, 77, 77, 1) !important;
+}
+
+.el-tree-node:focus > .el-tree-node__content {
+  background-color: #000000 !important;
+}
+
+.el-tree-node__content:hover {
+  background-color: #000000 !important;
+}
+
+.dateBar {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  margin-left: 20px;
+}
+
+.pickers {
+  margin-left: 20px;
+}
+
+.tables {
+  margin-top: 20px;
+  width: 95%;
+  margin-left: 3%;
+  position: relative;
+}
+
+.table {
+  background-color: rgba(77, 77, 77, 1) !important;
+}
+
+.el-table td,
+.el-table th.is-leaf {
+  border-bottom: 1px solid rgba(77, 77, 77, 1) !important;
+}
+
+.el-table__header {
+  width: 100% !important;
+}
+
+.el-table__body-wrapper {
+  background-color: rgba(77, 77, 77, 1) !important;
+}
+
+.el-table::before {
+  width: 0;
+}
+
+tr {
+  line-height: 1.5;
+  background: #1e1e1e;
+  margin-bottom: 2px;
+  border-radius: 5px;
+}
+
+.table-main {
+  font-size: 14px;
+  width: 600px;
+  text-align: center;
+  background: #000000;
+  margin: 5px;
+  border-collapse: separate;
+  border-spacing: 0px 5px;
+}
+
+.paginations {
+  display: flex;
+  flex-direction: row-reverse;
+}
+
+.titleinfoall {
+  display: flex;
+  position: absolute;
+  left: 10px;
+  bottom: 10px;
+}
+
+.showTitle {
+  color: #ffffff;
+  margin-right: 10px;
+}
+.fontSty {
+  font-size: 12px;
+}
+.fontSty1 {
+  font-weight: bold;
+}
+
+.showvalue {
+  color: #ffffff;
+  font-size: 14px;
+  font-weight: bold;
+  margin-right: 10px;
+}
+</style>
+
+<style lang="less">
+.el-dialog.currentBorder {
+  border: 1px solid #eee;
+}
+
+.el-card.otherContentBox {
+  background: rgb(36, 36, 36);
+
+  .el-descriptions__header {
+    color: #fff;
+  }
+
+  .el-descriptions__cell {
+    white-space: nowrap;
+  }
+
+  .el-descriptions__body {
+    color: #eee;
+    background: rgb(36, 36, 36);
+  }
+
+  .empSvg {
+    .el-empty__image {
+      opacity: 0.9;
+    }
+
+    .el-empty__description {
+      p {
+        color: #eee;
+      }
+    }
+  }
+}
+</style>

+ 0 - 0
src/components/search/calendar.vue


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff