Sfoglia il codice sorgente

完成告警详情页

夜仔 3 anni fa
parent
commit
180de7eaf6

+ 132 - 2
src/App.vue

@@ -1,6 +1,31 @@
 <template>
   <div id="app">
-    <router-view/>
+    <div class="headerBox">
+      <div class="headerLeft">
+        <div>{{ dateDay }}</div>
+        <div class="time">{{ dataTime }}</div>
+        <div class="week">{{ timeWeek }}</div>
+        <div class="address">{{$store.state.weaterRes.aqiDetail.area}}</div>
+        <div class="weather">
+          <img :src="$store.state.weaterRes.weather_pic || ''" alt="" />
+        </div>
+        <div>
+          {{ $store.state.weaterRes.weather || "" }}
+          {{ $store.state.weaterRes.temperature || "" }}℃
+        </div>
+      </div>
+      <div class="headerCenter" @click="routerGo('/')"></div>
+      <div class="headerRight">
+        <div class="boxBgRight" @click="openWindow">
+          <img src="./assets/image/headerIcon.png" alt="" />巡检维保
+        </div>
+        <div class="boxBgRight" @click="routerGo('/info-page')">
+          <img src="./assets/image/headerIcon.png" alt="" />告警详情
+        </div>
+        <div class="textBox">当前待处理:{{coverMap.unOline + coverMap.malfunction}}</div>
+      </div>
+    </div>
+    <router-view @coverMapChange ='coverMapChange' class="viewBox"/>
   </div>
 </template>
 
@@ -8,14 +33,53 @@
 export default {
   data() {
     return {
+      dateDay: "",
+      dataTime: "",
+      timeArea: "",
+      dataWeekList: ["一", "二", "三", "四", "五", "六", "七"],
+      timeWeek: "",
+      coverMap:{
+        unOline:0,
+        deviceTotalNum:0,
+        malfunction:0,
+      },
       resizeTime: true,
     };
   },
   mounted(){
     this.getWeater()
+    setInterval(() => {
+      let day = new Date();
+      this.dateDay =
+        day.getFullYear() +
+        "-" +
+        (day.getMonth() + 1 < 10
+          ? "0" + (day.getMonth() + 1)
+          : "" + (day.getMonth() + 1)) +
+        "-" +
+        (day.getDate() < 10 ? "0" + day.getDate() : day.getDate());
+      this.timeWeek = " 星期" + this.dataWeekList[day.getDay()-1];
+      this.dataTime =
+        (day.getHours() < 10 ? "0" + day.getHours() : day.getHours()) +
+        ":" +
+        (day.getMinutes() < 10 ? "0" + day.getMinutes() : day.getMinutes()) +
+        ":" +
+        (day.getSeconds() < 10 ? "0" + day.getSeconds() : day.getSeconds());
+    }, 1000);
     window.addEventListener("resize", () => this.resizeTimeActions(), true);
   },
   methods:{
+    coverMapChange(val){
+      console.log(val)
+        this.coverMap = val
+    },
+    routerGo(router){
+      this.$router.push(router)
+    },
+    // 点击跳转
+    openWindow(){
+      window.open('http://121.40.217.77:8080/YtIoTJX/view/proform/index.jsp?theme=access')
+    },
     resizeTimeActions() {
       if (!this.resizeTime) return;
       this.resizeTime = false;
@@ -25,7 +89,7 @@ export default {
       }, 300);
     },
     async getWeater(){
-        let res = await this.$axios.get('/top/listWeather?'+this.$qs.stringify({
+        let res = await this.$axios.get('/jx/top/listWeather?'+this.$qs.stringify({
         area: '上饶市'
       }))
       if(res.success){
@@ -36,10 +100,76 @@ export default {
 }
 </script>
 
+<style lang="scss" scoped>
+    .headerBox {
+        width: 100%;
+        height: 80px;
+        background: url('./assets/image/header.png');
+        background-size: 100% 100%;
+        display: flex;
+        .headerLeft,
+        .headerRight {
+            width: 620px;
+            // background: #000;
+            display: flex;
+            // justify-content: space-between;
+            align-items: center;
+            height: 50px;
+        }
+        .headerLeft {
+            padding: 0 20px;
+            box-sizing: border-box;
+            line-height: 20px;
+            div {
+                margin-right: 20px;
+            }
+            .week {
+                margin-right: 70px;
+            }
+            img {
+                width: 29px;
+            }
+        }
+        .headerCenter {
+            flex: 1;
+        }
+        .headerRight {
+            // justify-content: space-between;
+            padding-right: 30px;
+            box-sizing: border-box;
+            .boxBgRight {
+                width: 175px;
+                height: 50px;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                background: url('./assets/image/boxTitle.png');
+                background-size: 100% 100%;
+                line-height: 18px;
+                cursor: pointer;
+                img {
+                    margin-right: 5px;
+                    width: 18px;
+                    height: 18px;
+                }
+            }
+            .textBox{
+              flex: 1;
+              text-align: right;
+            }
+        }
+    }
+    .viewBox{
+      height: calc(100% - 80px);
+      width: 100%;
+    }
+</style>
 <style lang="scss">
 #app {
   width: 100%;
   height: 100%;
+  background: #06162A;
+  color: #FFF;
 }
 body,
 div,

BIN
src/assets/image/xh0.png


BIN
src/assets/image/xh1.png


BIN
src/assets/image/xh2.png


BIN
src/assets/image/xh3.png


BIN
src/assets/image/xh4.png


BIN
src/assets/trade/down.png


BIN
src/assets/trade/up.png


+ 6 - 7
src/plugins/axios.js

@@ -3,12 +3,11 @@ import { Notify } from "vant";
 import Vue from 'vue';
 import axios from "axios";
 // Full config:  https://github.com/axios/axios#request-config
-axios.defaults.baseURL = 'http://121.40.217.77:8082/';
-// axios.defaults.baseURL = 'https://121.40.217.77:8084/';
-console.log(axios.defaults.baseURL)
-    // axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
-    // axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
-    // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
+// if (process.env.NODE_ENV !== "development") axios.defaults.baseURL = 'http://121.40.217.77:8085';
+axios.defaults.baseURL = 'http://121.40.217.77:8085';
+// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
+// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
+// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
 
 let config = {
     // baseURL: process.env.baseURL || process.env.apiUrl || ""
@@ -33,7 +32,7 @@ _axios.interceptors.request.use(
 _axios.interceptors.response.use(
     function(response) {
         // Do something with response data
-        if (!response.data.success) Notify({ type: 'danger', message: response.data.message })
+        // if (!response.data.success) Notify({ type: 'danger', message: response.data.message })
         return response.data;
     },
     function(error) {

+ 5 - 0
src/router/index.js

@@ -8,6 +8,11 @@ const routes = [{
     name: 'Home',
     component: () =>
         import ( /* webpackChunkName: "about" */ '../views/home')
+}, {
+    path: '/info-page',
+    name: 'infoPage',
+    component: () =>
+        import ( /* webpackChunkName: "about" */ '../views/infoPage')
 }, ]
 
 const router = new VueRouter({

+ 8 - 1
src/store/index.js

@@ -5,8 +5,15 @@ Vue.use(Vuex)
 
 export default new Vuex.Store({
     state: {
-        weaterRes: {},
+        weaterRes: {
+            aqiDetail: {},
+            weather_pic: '',
+            weather: '',
+            temperature: '',
+        },
         windowWidth: 1920 + 1080,
+        wsUrl: process.env.NODE_ENV === "development" ? '172.16.120.92:8085' : '121.40.217.77:8085',
+        // wsUrl: '121.40.217.77:8085',
     },
     mutations: {
         changClient(state, val) {

+ 12 - 11
src/views/home/echarts1.js

@@ -1,10 +1,5 @@
 import * as echarts from "echarts";
-export default function getData() {
-    let params = [
-        [20, 22, 11, 24, 20, 30, 10],
-        [20, 32, 19, 34, 19, 30, 20]
-    ]
-    console.log(params)
+export default function getData(params) {
     return {
         color: ['rgba(77,237,255,1)', 'rgba(228,46,121,1)', ],
         tooltip: {
@@ -18,8 +13,8 @@ export default function getData() {
         },
         toolbox: {},
         grid: {
-            left: 0,
-            right: 10,
+            left: 10,
+            right: 25,
             bottom: 0,
             top: 20,
             containLabel: true
@@ -29,17 +24,23 @@ export default function getData() {
             boundaryGap: false,
             axisLabel: {
                 color: "#FFFFFF",
+                formatter: function(param) {
+                    return `${param.slice(5, 10)}`;
+                },
             },
             axisTick: {
                 show: false,
             },
-            data: ['1', '2', '3', '4', '5', '6', '7']
+            data: params.map(val => val.time)
         }],
         yAxis: [{
             type: 'value',
             axisLabel: {
                 color: "#FFFFFF",
             },
+            max: function(value) {
+                return value.max + value.max * 0.2;
+            },
             axisTick: {
                 show: false,
             },
@@ -72,7 +73,7 @@ export default function getData() {
                 emphasis: {
                     focus: 'series'
                 },
-                data: params[0]
+                data: params.map(val => val.offline)
             },
             {
                 name: '异常警告',
@@ -96,7 +97,7 @@ export default function getData() {
                 emphasis: {
                     focus: 'series'
                 },
-                data: params[1]
+                data: params.map(val => val.total - val.offline)
             },
         ]
     };

+ 8 - 7
src/views/home/echarts2.js

@@ -1,11 +1,10 @@
 import * as echarts from "echarts";
-export default function getData() {
-    let data = Array.from(Array(7)).map((val, ind) => {
-        let day = new Date(new Date().getTime() - (7 - ind - 1) * 24 * 60 * 60 * 1000)
+export default function getData(data) {
+    data = data.map(val => {
         return {
-            day: (day.getMonth() + 1) + "." + (day.getDate() < 10 ? "0" + day.getDate() : day.getDate()),
+            ...val,
             val: {
-                value: Math.ceil(Math.random() * 10),
+                value: val.value,
                 itemStyle: {
                     color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
                         offset: 0,
@@ -22,10 +21,12 @@ export default function getData() {
         color: ["rgba(4,187,255,1)"],
         xAxis: {
             type: "category",
-            // data: data.map(val => val.day),
-            data: data.map((val, ind) => ind + 1),
+            data: data.map(val => val.createTime),
             axisLabel: {
                 color: "#FFFFFF",
+                formatter: function(param) {
+                    return `${param.slice(5, 10)}`;
+                },
             },
             axisTick: {
                 show: false,

+ 2 - 57
src/views/home/index.scss

@@ -1,63 +1,7 @@
 .home {
-    height: 100%;
-    width: 100%;
-    background: #06162A;
-    color: #FFF;
-    .headerBox {
-        width: 100%;
-        height: 80px;
-        background: url('../../assets/image/header.png');
-        background-size: 100% 100%;
-        display: flex;
-        .headerLeft,
-        .headerRight {
-            width: 620px;
-            // background: #000;
-            display: flex;
-            // justify-content: space-between;
-            align-items: center;
-            height: 50px;
-        }
-        .headerLeft {
-            padding: 0 20px;
-            box-sizing: border-box;
-            div {
-                margin-right: 20px;
-            }
-            .week {
-                margin-right: 70px;
-            }
-            img {
-                width: 29px;
-            }
-        }
-        .headerCenter {
-            flex: 1;
-        }
-        .headerRight {
-            justify-content: space-between;
-            padding-right: 30px;
-            box-sizing: border-box;
-            .boxBgRight {
-                width: 175px;
-                height: 50px;
-                display: flex;
-                justify-content: center;
-                align-items: center;
-                background: url('../../assets/image/boxTitle.png');
-                background-size: 100% 100%;
-                line-height: 18px;
-                img {
-                    margin-right: 5px;
-                    width: 18px;
-                    height: 18px;
-                }
-            }
-        }
-    }
     .contentBox {
         width: 100%;
-        height: calc(100% - 80px);
+        height: 100%;
         padding-bottom: 10px;
         box-sizing: border-box;
         display: flex;
@@ -81,6 +25,7 @@
                 display: flex;
                 flex-direction: column;
                 flex-wrap: wrap;
+                cursor: pointer;
                 // border: 1px solid #00d2ff;
                 span {
                     // width: 80px;

+ 357 - 185
src/views/home/index.vue

@@ -1,36 +1,20 @@
 <template>
   <div class="home">
-    <div class="headerBox">
-      <div class="headerLeft">
-        <div>{{ dateDay }}</div>
-        <div class="time">{{ dataTime }}</div>
-        <div class="week">{{ timeWeek }}</div>
-        <div class="address">{{$store.state.weaterRes.aqiDetail.area}}</div>
-        <div class="weather">
-          <img :src="$store.state.weaterRes.weather_pic || ''" alt="" />
-        </div>
-        <div>
-          {{ $store.state.weaterRes.weather || "" }}
-          {{ $store.state.weaterRes.temperature || "" }}℃
-        </div>
-      </div>
-      <div class="headerCenter"></div>
-      <div class="headerRight">
-        <div class="boxBgRight">
-          <img src="../../assets/image/headerIcon.png" alt="" />巡检维保
-        </div>
-        <div>当前待处理:5</div>
-      </div>
-    </div>
     <div class="contentBox">
       <div class="mapBox">
         <div class="Amap" id="mapF"></div>
         <div class="rightIconBox">
-          <div @click="isTypeMap('isNormal')"><img src="../../assets/image/zcIcon.png" alt="" />正常</div>
+          <div @click="isTypeMap('isNormal')">
+            <img src="../../assets/image/zcIcon.png" alt="" />正常
+          </div>
           <span></span>
-          <div @click="isTypeMap('isWarning')"><img src="../../assets/image/jcIcon.png" alt="" />告警</div>
+          <div @click="isTypeMap('isWarning')">
+            <img src="../../assets/image/jcIcon.png" alt="" />告警
+          </div>
           <span></span>
-          <div @click="isTypeMap('isLine')"><img src="../../assets/image/lxIcon.png" alt="" />离线</div>
+          <div @click="isTypeMap('isLine')">
+            <img src="../../assets/image/lxIcon.png" alt="" />离线
+          </div>
         </div>
       </div>
       <div class="echartsBox">
@@ -39,20 +23,59 @@
           <div class="echartsBoxList box1">
             <div class="box1Left">
               <img src="../../assets/image/jg.png" alt="" />
-              <span>井盖总数(100)</span>
+              <span>井盖总数({{ coverMap.deviceTotalNum }})</span>
             </div>
             <div class="box1Right">
-              <div>井盖在线数:<span class="green">90</span></div>
-              <div>在线率:<span class="green">90%</span></div>
-              <div>离线告警数:<span class="yellow">5</span></div>
-              <div>离线率:<span class="yellow">5%</span></div>
-              <div>异常告警数:<span class="red">5</span></div>
-              <div>告警率:<span class="red">5%</span></div>
+              <div>
+                井盖在线数:<span class="green">{{
+                  coverMap.deviceTotalNum - coverMap.unOline
+                }}</span>
+              </div>
+              <div>
+                在线率:<span class="green"
+                  >{{
+                    (coverMap.deviceTotalNum &&
+                      (
+                        (coverMap.deviceTotalNum - coverMap.unOline) /
+                        coverMap.deviceTotalNum
+                      ).toFixed(2) * 100) ||
+                    0
+                  }}%</span
+                >
+              </div>
+              <div>
+                离线告警数:<span class="yellow">{{ coverMap.unOline }}</span>
+              </div>
+              <div>
+                离线率:<span class="yellow"
+                  >{{
+                    (coverMap.deviceTotalNum &&
+                      (coverMap.unOline / coverMap.deviceTotalNum).toFixed(2) *
+                        100) ||
+                    0
+                  }}%</span
+                >
+              </div>
+              <div>
+                异常告警数:<span class="red">{{ coverMap.malfunction }}</span>
+              </div>
+              <div>
+                告警率:<span class="red"
+                  >{{
+                    (coverMap.deviceTotalNum &&
+                      (coverMap.malfunction / coverMap.deviceTotalNum).toFixed(
+                        2
+                      ) * 100) ||
+                    0
+                  }}%</span
+                >
+              </div>
             </div>
           </div>
         </div>
         <div>
-          <div class="titleBox">近7日告警情况统计</div>
+          <div class="titleBox">近期告警情况统计</div>
+          <!-- <div class="titleBox">近7日告警情况统计</div> -->
           <div class="echartsBoxList">
             <div ref="echartD1" class="echartD"></div>
           </div>
@@ -75,48 +98,54 @@
             :highlight-current-row="false"
           >
             <el-table-column
-              prop="name"
+              prop="devId"
               label="设备编号"
               :min-width="20"
               show-overflow-tooltip
             >
             </el-table-column>
             <el-table-column
-              prop="dpName"
+              prop="serial"
               label="告警类型"
               :min-width="20"
               show-overflow-tooltip
             >
+              <template slot-scope="scope">
+                {{
+                  scope.row.serial == 1
+                    ? "离线"
+                    : scope.row.serial == 2
+                    ? "异动"
+                    : scope.row.serial == 3
+                    ? "液位告警"
+                    : scope.row.serial == 32
+                    ? "故障"
+                    : ""
+                }}
+              </template>
             </el-table-column>
             <el-table-column
-              prop="jf"
-              label="负责人"
-              :min-width="20"
-              show-overflow-tooltip
-            >
-            </el-table-column>
-            <el-table-column
-              prop="zl"
-              label="联系方式"
+              prop="value"
+              label="告警内容"
               :min-width="20"
               show-overflow-tooltip
             >
             </el-table-column>
             <el-table-column
-              prop="je"
-              label="位置"
+              prop="deviceName"
+              label="设备名称"
               :min-width="20"
               show-overflow-tooltip
             >
             </el-table-column>
             <el-table-column
-              prop="time"
+              prop="timeStamp"
               label="告警时间"
               :min-width="20"
               show-overflow-tooltip
             >
             </el-table-column>
-            <el-table-column
+            <!-- <el-table-column
               prop="time"
               label="处理状态"
               :min-width="20"
@@ -129,7 +158,7 @@
                   >{{ scope.$index > 2 ? "已处理" : "未处理" }}</el-tag
                 >
               </template>
-            </el-table-column>
+            </el-table-column> -->
           </el-table>
         </div>
       </div>
@@ -144,92 +173,41 @@ import * as echarts from "echarts";
 import getDataE1 from "./echarts1";
 import getDataE2 from "./echarts2";
 import AMap from "AMap";
-import xh from "../../assets/image/xh.png";
-import dc from "../../assets/image/dc.png";
+// import xh from "../../assets/image/xh.png";
+// import xh0 from "../../assets/image/xh0.png";
+// import xh1 from "../../assets/image/xh1.png";
+// import xh2 from "../../assets/image/xh2.png";
+// import xh3 from "../../assets/image/xh3.png";
+// import xh4 from "../../assets/image/xh4.png";
+// import dc from "../../assets/image/dc.png";
 import zcIcon from "../../assets/image/zcIcon.png";
 import jcIcon from "../../assets/image/jcIcon.png";
 import lxIcon from "../../assets/image/lxIcon.png";
 export default {
   data() {
     return {
-      dateDay: "",
-      dataTime: "",
-      timeArea: "",
-      timeWeek: "",
-      weatherObj: {},
       map: null,
       echartsBox1: null,
       echartsBox2: null,
-      dataWeekList: ["一", "二", "三", "四", "五", "六", "七"],
-      tableData: [
-        {
-          name: "0021",
-          dpName: "液位过高",
-          jf: "周文斌",
-          zl: "13571202367",
-          je: "江西省上饶市",
-          time: "15:23:26",
-        },
-        {
-          name: "0022",
-          dpName: "运行异常",
-          jf: "周文斌",
-          zl: "13571202367",
-          je: "江西省上饶市",
-          time: "15:22:00",
-        },
-        {
-          name: "0023",
-          dpName: "液位过高",
-          jf: "周文斌",
-          zl: "13571202367",
-          je: "江西省上饶市",
-          time: "15:21:00",
-        },
-        {
-          name: "0024",
-          dpName: "运行异常",
-          jf: "周文斌",
-          zl: "13571202367",
-          je: "江西省上饶市",
-          time: "15:20:00",
-        },
-        {
-          name: "0025",
-          dpName: "液位过高",
-          jf: "周文斌",
-          zl: "13571202367",
-          je: "江西省上饶市",
-          time: "15:19:00",
-        },
-        {
-          name: "0026",
-          dpName: "运行异常",
-          jf: "周文斌",
-          zl: "13571202367",
-          je: "江西省上饶市",
-          time: "15:18:00",
-        },
-        {
-          name: "0027",
-          dpName: "运行异常",
-          jf: "周文斌",
-          zl: "13571202367",
-          je: "江西省上饶市",
-          time: "15:17:00",
-        },
-      ],
+      tableData: [],
       lnglats: [
-        { x: 118.004933, y: 28.47108, type: 1 },
-        { x: 118.004205, y: 28.470654, type: 2 },
-        { x: 118.005709, y: 28.471602, type: 3 },
+        // { x: 118.004933, y: 28.47108, type: 1 },
+        // { x: 118.004205, y: 28.470654, type: 2 },
+        // { x: 118.005709, y: 28.471602, type: 3 },
       ],
-      mapListType:{
+      mapListType: {
         isNormal: true,
         isWarning: true,
         isLine: true,
       },
-      overlayGroupMap:[]
+      overlayGroupMap: [],
+      coverMap: {
+        unOline: 0,
+        deviceTotalNum: 0,
+        malfunction: 0,
+      },
+      infoWindow: null,
+      ws: "",
     };
   },
   watch: {
@@ -242,43 +220,94 @@ export default {
   mounted() {
     this.getData();
     this.initMap();
-    setInterval(() => {
-      let day = new Date();
-      this.dateDay =
-        day.getFullYear() +
-        "-" +
-        (day.getMonth() + 1 < 10
-          ? "0" + (day.getMonth() + 1)
-          : "" + (day.getMonth() + 1)) +
-        "-" +
-        (day.getDate() < 10 ? "0" + day.getDate() : day.getDate());
-      this.timeWeek = " 星期" + this.dataWeekList[day.getDay()];
-      this.dataTime =
-        (day.getHours() < 10 ? "0" + day.getHours() : day.getHours()) +
-        ":" +
-        (day.getMinutes() < 10 ? "0" + day.getMinutes() : day.getMinutes()) +
-        ":" +
-        (day.getSeconds() < 10 ? "0" + day.getSeconds() : day.getSeconds());
-    }, 1000);
   },
   methods: {
-    isTypeMap(val){
-      console.log(val)
-      this.mapListType[val] = !this.mapListType[val]
+    // 地图标点的设备状态控制显示
+    isTypeMap(val) {
+      this.mapListType[val] = !this.mapListType[val];
       let type = val === "isNormal" ? 1 : val === "isWarning" ? 2 : 3;
-      let markers = this.lnglats.filter(val=>val.type === type)
-      let marksList = this.overlayGroupMap.getOverlays().filter(element => element.getExtData().type === type);
-      if(this.mapListType[val]){
+      let markers = this.lnglats.filter((val) => val.type === type);
+      let marksList = this.overlayGroupMap
+        .getOverlays()
+        .filter((element) => element.getExtData().type === type);
+      if (this.mapListType[val]) {
         this.overlayGroupMap.addOverlays(this.addMarker(markers));
-      }else {
+      } else {
         this.overlayGroupMap.removeOverlays(marksList);
+        console.log();
+        this.infoWindow &&
+          this.infoWindow.getIsOpen() &&
+          marksList.some(
+            (val) =>
+              val.getPosition().lng == this.infoWindow.getPosition().lng &&
+              val.getPosition().lat == this.infoWindow.getPosition().lat
+          ) &&
+          this.infoWindow.close();
       }
     },
+    // 初始加载
     async getData() {
       this.echartsBox1 = echarts.init(this.$refs.echartD1);
-      this.echartsBox1.setOption(getDataE1());
       this.echartsBox2 = echarts.init(this.$refs.echartD2);
-      this.echartsBox2.setOption(getDataE2());
+      this.getCover();
+      this.getListYw();
+      this.getAlarmsSe();
+      this.getDevcie();
+      this.getDataWs();
+    },
+    // 整体情况
+    async getCover() {
+      let res = await this.$axios.get("/jx/top/listDeviceStatus");
+      if (res.data) {
+        this.coverMap = res.data;
+        this.$emit("coverMapChange", res.data);
+      }
+    },
+    // 地图标点
+    async getDevcie() {
+      let res = await this.$axios.get("/jx/top/listDevcie");
+      if (res.data) {
+        this.lnglats = res.data.map((val) => {
+          return {
+            ...val,
+            x: val.longitude,
+            y: val.dimension,
+            type:
+              Object.keys(val.data).length === 0 ||
+              val.data.dp.find((value) => value.serial == 1)
+                ? 3
+                : val.data.dp.find(
+                    (value) =>
+                      value.serial == 2 ||
+                      value.serial == 32 ||
+                      value.serial == 3
+                  )
+                ? 2
+                : 1,
+          };
+        });
+        this.overlayGroupMap = new AMap.OverlayGroup(
+          this.addMarker(this.lnglats)
+        );
+        this.map.add(this.overlayGroupMap);
+        this.map.setFitView(); // 根据所有点自适应
+      }
+    },
+    // 告警情况
+    async getAlarmsSe() {
+      let res = await this.$axios.get("/jx/top/listAlarmsSe");
+      if (res.data) {
+        this.echartsBox1.setOption(getDataE1(res.data));
+      }
+    },
+    // 液位情况
+    async getListYw(val) {
+      let res = await this.$axios.get(
+        "/jx/top/listYw" + (val ? "?devId=" + val : "")
+      );
+      if (res.data) {
+        this.echartsBox2.setOption(getDataE2(res.data));
+      }
     },
     async initMap() {
       this.map = await new AMap.Map("mapF", {
@@ -315,73 +344,216 @@ export default {
         });
         this.map.addControl(geolocation);
       });
-      this.overlayGroupMap = new AMap.OverlayGroup(this.addMarker())
-      this.map.add(this.overlayGroupMap);
-      this.map.setFitView(); // 根据所有点自适应
     },
-    addMarker(lnglats = this.lnglats, type) {
+    // 添加标点
+    addMarker(lnglats = this.lnglats) {
       // 创建标点和点击事件
       let icon = "";
-      return lnglats.map((val, ind) => {
-        if (type !== "water") {
-          icon =
-            val.type == 1
-              ? zcIcon
-              : val.type == 2
-              ? jcIcon
-              : val.type == 3
-              ? lxIcon
-              : zcIcon;
-        }
-        console.log(icon);
+      return lnglats.map((val) => {
+        icon =
+          val.type == 1
+            ? zcIcon
+            : val.type == 2
+            ? jcIcon
+            : val.type == 3
+            ? lxIcon
+            : zcIcon;
         let marker = new AMap.Marker({
           position: new AMap.LngLat(val.x, val.y),
           icon: icon || "",
           zIndex: 9,
           extData: {
-            id: ind + 1,
-            type:val.type
+            id: val.devId,
+            type: val.type,
+            val: val,
           },
         });
         marker.on("click", async () => {
           await this.addMarkerInfo([val.x, val.y], val);
+          this.getListYw(val.devId);
         });
         return marker;
       });
     },
-    // 添加标点
+    // 标点弹窗
     addMarkerInfo(position, value) {
       // this.map.getIsOpen();
       this.map.clearInfoWindow();
-      var infoWindow = new AMap.InfoWindow({
+      this.infoWindow = new AMap.InfoWindow({
         isCustom: true, //使用自定义窗体
         closeWhenClickMap: true,
+        // <img src="${value.data.dp && value.data.dp.find(val=>val.serial == 66) ? value.data.dp.find(val=>val.serial == 67).value + '米' : '---'}" alt="">
+        // <img src="${dc}" alt="">
+        // <div>3.6V</div>
         content: `
                 <div class="mapTab">
-                  <div class="closeInfo ${value.type === 1  ? 'green' : value.type === 2  ? 'red' : 'gray'}">${value.type === 1  ? '正常' : value.type === 2  ? '告警' : '离线'}</div>
+                  <div class="closeInfo ${
+                    value.type === 1
+                      ? "green"
+                      : value.type === 2
+                      ? "red"
+                      : "gray"
+                  }">${
+          value.type === 1 ? "正常" : value.type === 2 ? "告警" : "离线"
+        }</div>
                   <div class="tableTitle">
-                    <img src="${xh}" alt="">
-                    <img src="${dc}" alt="">
-                    <div>98%</div>
-                    <div>3.6V</div>
+                    <div>信号:${
+                      value.data.dp &&
+                      value.data.dp.find((val) => val.serial == 66)
+                        ? value.data.dp.find((val) => val.serial == 66).value
+                        : "---"
+                    }</div>
+                    <div>电量:${
+                      value.data.dp &&
+                      value.data.dp.find((val) => val.serial == 65)
+                        ? value.data.dp.find((val) => val.serial == 65).value +
+                          "%"
+                        : "---"
+                    }</div>
                   </div>    
                   <div class="tableContent">
-                    <div class="yztBox ${value.type === 2  ? 'waning' : 'gray'}"">
-                      <div class="${value.type === 1  ? 'green' : value.type === 2  ? 'white' : 'gray'}">${value.type === 1  ? '正常' : value.type === 2  ? '水位过高' : '---'}</div>
+                    <div class="yztBox ${
+                      value.type === 2 &&
+                      value.data.dp &&
+                      value.data.dp.find((val) => val.serial == 3)
+                        ? "waning"
+                        : "gray"
+                    }"">
+                      <div class="${
+                        value.type === 3
+                          ? "gray"
+                          : value.type === 2 &&
+                            value.data.dp &&
+                            value.data.dp.find((val) => val.serial == 3)
+                          ? "white"
+                          : "green"
+                      }">${
+          value.type === 3
+            ? "---"
+            : value.type === 2 && value.data.dp.find((val) => val.serial == 3)
+            ? "水位过高"
+            : "正常"
+        }</div>
                       <div>实时水况</div>
                     </div>
-                    <div><span>运行状态:</span><b class="${value.type === 1  ? 'green' : value.type === 2  ? 'red' : 'gray'}">${value.type === 1  ? '运行正常' : value.type === 2  ? '井盖打开' : '设备离线'}</b></div>
-                    <div><span>实时水位:</span>${value.type === 1  ? '1米' : value.type === 2  ? '10米' : '---'}</div>
-                    <div><span>负责人:</span>张三</div>
-                    <div><span>联系电话:</span>13666666666</div>
-                    <div><span>时间:</span>2021-08-19 15:12:12</div>
-                    <div><span>位置:</span>上海市青浦区徐乐路208号</div>
+                    <div><span>运行状态:</span><b class="${
+                      value.type === 1
+                        ? "green"
+                        : value.type === 2
+                        ? "red"
+                        : "gray"
+                    }">${
+          value.type === 1
+            ? "运行正常"
+            : value.type === 2 && value.data.dp.find((val) => val.serial == 2)
+            ? "异动"
+            : value.type === 2 && value.data.dp.find((val) => val.serial == 32)
+            ? "故障"
+            : value.type === 2 && value.data.dp.find((val) => val.serial == 3)
+            ? "液位告警"
+            : "设备离线"
+        }</b></div>
+                    <div><span>实时水位:</span>${
+                      value.data.dp &&
+                      value.data.dp.find((val) => val.serial == 67)
+                        ? value.data.dp.find((val) => val.serial == 67).value +
+                          "米"
+                        : "---"
+                    }</div>
+                    <div><span>负责人:</span>${value.userName || "---"}</div>
+                    <div><span>联系电话:</span>${value.phone || "---"}</div>
+                    <div><span>时间:</span>${
+                      value.data.timeStamp || "---"
+                    }</div>
+                    <div><span>位置:</span>${value.addr || "---"}</div>
                   </div>
-                  <div class="sbh">设备号:868646515</div>
+                  <div class="sbh">设备号:${value.devId || "---"}</div>
                 </div>`,
         offset: new AMap.Pixel(0, -30),
       });
-      infoWindow.open(this.map, position);
+      this.infoWindow.open(this.map, position);
+    },
+    async getDataWs() {
+      if ("WebSocket" in window) {
+        this.ws = new WebSocket(
+          "ws://" + this.$store.state.wsUrl + "/top/WS/alarmPush"
+        );
+        this.ws.onopen = () => {
+          console.log("websocket连接成功");
+          // this.sendWs({aa:22});
+        };
+
+        this.ws.onmessage = (resJson) => {
+          let res = JSON.parse(resJson.data);
+          let data = res.dp.map((val) => {
+            return {
+              ...val,
+              ...res,
+            };
+          });
+          this.tableData.unshift(...data);
+          this.lnglats.forEach((val) => {
+            if (val.devId === res.devId) {
+              val.data = res;
+              val.type =
+                Object.keys(val.data).length === 0 ||
+                val.data.dp.find((value) => value.serial == 1)
+                  ? 3
+                  : val.data.dp.find(
+                      (value) =>
+                        value.serial == 2 ||
+                        value.serial == 32 ||
+                        value.serial == 3
+                    )
+                  ? 2
+                  : 1;
+            }
+          });
+          let marksList = this.overlayGroupMap
+            .getOverlays()
+            .filter((element) => element.getExtData().id === res.devId);
+          let resData = this.lnglats.find((val) => val.devId == res.devId);
+          // 判断弹窗不为null 判断弹窗是否打开 判断弹窗位置和当前更改位置是否一致  关闭弹窗
+          // this.infoWindow && this.infoWindow.getIsOpen() && marksList.some(val=> val.getPosition().lng == this.infoWindow.getPosition().lng && val.getPosition().lat == this.infoWindow.getPosition().lat) && this.infoWindow.close()
+          this.infoWindow &&
+            this.infoWindow.getIsOpen() &&
+            this.infoWindow.close();
+          marksList.length > 0 &&
+            this.overlayGroupMap.removeOverlays(marksList);
+          resData &&
+            this.overlayGroupMap.addOverlays(this.addMarker([resData]));
+          resData && this.addMarkerInfo([resData.x, resData.y], resData);
+        };
+
+        this.ws.onclose = () => {
+          // 关闭 websocket
+          console.log("连接已关闭...");
+
+          //断线重新连接
+          setTimeout(() => {
+            this.getData();
+          }, 2000);
+        };
+      } else {
+        // 浏览器不支持 WebSocket
+        console.log("您的浏览器不支持 WebSocket!");
+      }
+      //  let res = await this.$axios.get(this.resInfo.apiAddr + '?' +this.$qs.stringify({
+      //   applicationCode: this.resInfo.applicationCode
+      // }))
+      // if(res.success){
+      //   this.resList = res.data
+      // }
+    },
+    sendWs(val) {
+      if (this.ws && this.ws.readyState == 1) {
+        this.ws.send(JSON.stringify(val));
+        console.log("发送成功");
+      } else {
+        setTimeout(() => {
+          this.sendWs(val);
+        }, 100);
+      }
     },
   },
 };
@@ -470,7 +642,7 @@ export default {
         line-height: 27px;
       }
     }
-    .waning{
+    .waning {
       background: url("../../assets/image/yc.png");
     }
   }
@@ -482,8 +654,8 @@ export default {
     color: rgba(255, 1, 1, 1);
     font-weight: bold;
   }
-  .white{
-    color: #FFF;
+  .white {
+    color: #fff;
     font-weight: bold;
   }
   .gray {

+ 415 - 0
src/views/infoPage/index.vue

@@ -0,0 +1,415 @@
+<template>
+  <div class="mainBox">
+    <div class="headerB">
+      <!-- <div class="headerBBox yellowBox">
+        <div class="number">136</div>
+        <div>
+          <div class="textF">总摊位数量(个)</div>
+          <div>+1.16% <img src="../../assets/trade/up.png" alt="" /></div>
+        </div>
+      </div> -->
+      <div class="headerBBox">
+        <div class="textF">未处理数量</div>
+        <div class="number">{{ totalObj.untreated }}</div>
+      </div>
+      <div class="headerBBox">
+        <div class="textF">告警数量</div>
+        <div class="number">{{ totalObj.total }}</div>
+      </div>
+      <div class="headerBBox">
+        <div class="textF">离线数量</div>
+        <div class="number">{{ totalObj.offline }}</div>
+      </div>
+      <div class="headerBBox">
+        <div class="textF">电量告警数量</div>
+        <div class="number">{{ totalObj.DL }}</div>
+      </div>
+      <div class="headerBBox">
+        <div class="textF">异动告警数量</div>
+        <div class="number">{{ totalObj.YD }}</div>
+      </div>
+      <div class="headerBBox">
+        <div class="textF">液位告警数量</div>
+        <div class="number">{{ totalObj.YW }}</div>
+      </div>
+    </div>
+    <div class="contentBox">
+      <el-row class="search" v-if="typeList[typeFree].inputList.length > 0">
+        <template v-for="item in typeList[typeFree].inputList">
+          <el-input
+            v-if="item.type === 'input'"
+            v-model="inputObj[item.prop]"
+            :placeholder="item.name"
+            :key="item.symbol"
+          ></el-input>
+          <el-select
+            v-else-if="item.type === 'select'"
+            v-model="inputObj[item.prop]"
+            :placeholder="item.name"
+            :key="item.symbol"
+            clearable 
+          >
+            <el-option
+              v-for="item in item.options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </template>
+        <el-button type="primary" @click="getData()">查询</el-button>
+        <el-button type="primary" @click="reset()">重置</el-button>
+      </el-row>
+      <el-row class="tableBox">
+        <el-table
+          :data="tableData"
+          header-row-class-name="tableHeaderClass"
+          row-class-name="rowCalss"
+          style="width: 100%"
+          height="100%"
+        >
+          <el-table-column type="index" align="center" width="50" label="序号">
+          </el-table-column>
+          <el-table-column
+            align="center"
+            v-for="(item, ind) in typeList[typeFree].tableDataHeader"
+            :key="ind"
+            :prop="item.prop"
+            :label="item.name"
+          >
+            <template slot-scope="scope">
+              {{
+                item.prop === "serial"
+                  ? scope.row[item.prop] == 1
+                    ? "离线"
+                    : scope.row[item.prop] == 2
+                    ? "异动"
+                    : scope.row[item.prop] == 3
+                    ? "液位告警"
+                    : scope.row[item.prop] == 32
+                    ? "故障"
+                    : ""
+                  : item.prop === "status"
+                  ? ""
+                  : scope.row[item.prop]
+              }}
+              <el-tag
+                v-if="item.prop === 'status'"
+                style="cursor: pointer"
+                @click="isStatus(scope.row)"
+                :type="scope.row[item.prop] == 1 ? 'success' : 'danger'"
+                disable-transitions
+                >{{ scope.row[item.prop] == 1 ? "已处理" : "未处理" }}</el-tag
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-row>
+      <el-pagination
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page="currentPage"
+        :page-sizes="[30, 50, 100, 150]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      typeList: [
+        {
+          name: "操作日志查询",
+          tableDataHeader: [
+            {
+              prop: "deviceName",
+              name: "设备名称",
+            },
+            {
+              prop: "devId",
+              name: "设备编号",
+            },
+            {
+              prop: "devcieModel",
+              name: "设备型号",
+            },
+            {
+              prop: "deviceType",
+              name: "设备类型",
+            },
+            {
+              prop: "serial",
+              name: "告警类型",
+            },
+            {
+              prop: "value",
+              name: "告警内容",
+            },
+            {
+              prop: "timeStamp",
+              name: "告警时间",
+            },
+            {
+              prop: "status",
+              name: "告警状态",
+            },
+          ],
+          url: "/jx/top/listHistryAlarms",
+          inputList: [
+            {
+              type: "input",
+              prop: "devId",
+              name: "设备ID",
+              symbol: Symbol(),
+            },
+            {
+              type: "select",
+              options: [{ value: 0, label: "未处理" },{ value: 1, label: "已处理" },],
+              prop: "status",
+              name: "告警状态",
+              symbol: Symbol(),
+            },
+          ],
+        },
+      ],
+      inputObj: {},
+      totalObj: { untreated: 0, offline: 0, total: 0, DL: 0, YD: 0, YW: 0 },
+      typeFree: 0,
+      tableData: [],
+      currentPage: 1,
+      pageSize: 50,
+      total: 0,
+    };
+  },
+  created() {
+    this.inputObj = {};
+  },
+  mounted() {
+    this.getData();
+    this.getAlarmsTj();
+  },
+  methods: {
+    reset() {
+      for (const key in this.inputObj) {
+        this.inputObj[key] = "";
+      }
+    },
+    async isStatus(row) {
+      this.$confirm("是否修改该告警状态?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(async () => {
+            let res = await this.$axios.post("/jx/top/updateAlarm" + "?" +this.$qs.stringify({
+                Id:row.id
+            }));
+            if (res) {
+                this.getData();
+              this.$message({
+                type: "success",
+                message: "删除成功!",
+              });
+            }
+        })
+        .catch(() => {
+          //   this.$message({
+          //     type: 'info',
+          //     message: '已取消删除'
+          //   });
+        });
+    },
+    async getAlarmsTj() {
+      let res = await this.$axios.get("/jx/top/listHistryAlarmsTj");
+      this.totalObj = res.data;
+    },
+    async getData() {
+      let data = {
+        pageNo: this.currentPage,
+        size: this.pageSize,
+      };
+      Object.assign(data, this.inputObj);
+      let res = await this.$axios.get(
+        this.typeList[this.typeFree].url + "?" + this.$qs.stringify(data)
+      );
+      this.tableData = res.pageList.map((val) => {
+        return {
+          ...val,
+        };
+      });
+      this.total = res.totalCount;
+    },
+    handleSizeChange(val) {
+      this.pageSize = val;
+      this.getData();
+      console.log(`每页 ${this.pageSize} 条`);
+    },
+    handleCurrentChange(val) {
+      this.currentPage = val;
+      this.getData();
+      console.log(`当前页: ${this.currentPage}`);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.mainBox {
+  padding: 30px;
+  box-sizing: border-box;
+  .headerB {
+    height: 100px;
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    box-sizing: border-box;
+    .headerBBox {
+      flex: 1;
+      margin-right: 20px;
+      height: 100px;
+      background: #000;
+      border-top: 1px solid;
+      display: flex;
+      justify-content: space-between;
+      //   flex-direction: column;
+      padding: 15px;
+      box-sizing: border-box;
+      align-items: center;
+      font-family: "DS", "DS-B", "DS-BB", "DS-BS";
+      .number {
+        font-size: 36px;
+        font-weight: 500;
+        line-height: 32px;
+      }
+      .textF {
+        font-size: 18px;
+        color: #fff;
+      }
+    }
+    & > .headerBBox:last-child {
+      margin-right: 0;
+    }
+    & > .headerBBox:nth-child(1) {
+      background: rgba(225, 249, 72, 0.2);
+      color: #f9f348;
+      border-color: #fff948;
+    }
+    & > .headerBBox:nth-child(2) {
+      background: rgba(40, 251, 219, 0.2);
+      color: #29ffde;
+      border-color: rgba(40, 251, 219, 1);
+    }
+    & > .headerBBox:nth-child(3) {
+      background: rgba(255, 55, 55, 0.2);
+      color: rgba(255, 55, 55, 1);
+      border-color: rgba(255, 55, 55, 1);
+    }
+    & > .headerBBox:nth-child(4) {
+      background: rgba(42, 207, 255, 0.2);
+      color: rgba(42, 207, 255, 1);
+      border-color: rgba(42, 207, 255, 1);
+    }
+    & > .headerBBox:nth-child(5) {
+      background: rgba(255, 174, 0, 0.2);
+      color: rgba(255, 174, 0, 1);
+      border-color: rgba(255, 174, 0, 1);
+    }
+    & > .headerBBox:nth-child(6) {
+      background: rgba(0, 255, 96, 0.2);
+      color: rgba(0, 255, 96, 1);
+      border-color: rgba(0, 255, 96, 1);
+    }
+  }
+  .contentBox {
+    width: 100%;
+    padding-top: 20px;
+    box-sizing: border-box;
+    height: calc(100% - 100px);
+    display: flex;
+    flex-direction: column;
+    .search {
+      height: 50px;
+    }
+    .el-input,.el-select {
+      width: 300px;
+      margin-right: 10px;
+    }
+    .tableBox {
+      flex: 1;
+      width: 100%;
+    }
+    /deep/.el-pagination {
+      display: flex;
+      justify-content: flex-end;
+      padding: 20px 20px 0;
+      span {
+        color: #fff;
+      }
+    }
+  }
+}
+/deep/.el-table {
+  background: transparent;
+  color: #fff;
+  &::before {
+    display: none;
+  }
+  .tableHeaderClass,
+  .rowCalss {
+    height: 30px;
+    background: transparent;
+    color: #fff;
+    th,
+    td {
+      height: 30px;
+      background: transparent;
+      color: #fff;
+      border-color: rgba(44, 90, 101, 0.5);
+    }
+    td {
+      padding: 10px 0;
+    }
+    .cell {
+      line-height: 15px;
+    }
+    .el-tag {
+      height: 20px;
+      line-height: 20px;
+    }
+  }
+  .rowCalss {
+    &:hover {
+      background: transparent;
+      color: #fff;
+      th,
+      td {
+        background: transparent;
+        .cell {
+          color: #6dbfff;
+        }
+      }
+    }
+  }
+  .el-table__body-wrapper {
+    scrollbar-width: none;
+    /* firefox */
+    -ms-overflow-style: none;
+    /* IE 10+ */
+    overflow-x: hidden;
+    overflow-y: auto;
+    &::-webkit-scrollbar {
+      display: none;
+      // opacity: 0;
+      /* Chrome Safari */
+    }
+  }
+}
+</style>

+ 1 - 1
vue.config.js

@@ -19,7 +19,7 @@ module.exports = {
         proxy: {
             // 配置多个跨域
             '/': {
-                target: 'http://172.16.120.92:8082/', //跨域接口的地址
+                target: 'http://172.16.120.92:8085/', //跨域接口的地址
                 changeOrigin: false,
                 pathRewrite: {
                     '': '/'