Parcourir la source

feat: global alarm message box

Casper Dai il y a 2 ans
Parent
commit
10a377b554
3 fichiers modifiés avec 144 ajouts et 45 suppressions
  1. 140 0
      src/layout/components/Notify.vue
  2. 4 1
      src/layout/index.vue
  3. 0 44
      src/permission.js

+ 140 - 0
src/layout/components/Notify.vue

@@ -0,0 +1,140 @@
+<template>
+  <div
+    v-if="hasMsg"
+    class="c-notify"
+  >
+    <el-table :data="tableData">
+      <el-table-column
+        :label="title"
+        class-name="notify-column"
+        show-overflow-tooltip
+      >
+        <template slot-scope="scope">
+          <svg-icon
+            icon-class="v0-alarm"
+            :color="scope.row.color"
+          />
+          <span style="padding:10px">{{ scope.row.happenTime }} {{ scope.row.deviceName }} {{ scope.row.bugName }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        width="48"
+        align="right"
+      >
+        <template slot="header">
+          <span
+            class="has-active"
+            @click="onClear"
+          >
+            清空
+          </span>
+        </template>
+        <template slot-scope="scope">
+          <i
+            class="el-icon-delete has-active"
+            @click="delateRowMsg(scope)"
+          />
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import {
+  subscribe,
+  unsubscribe
+} from '@/utils/mqtt'
+
+const AlarmColors = ['#04A681', '#FFA000', '#F40645']
+
+export default {
+  name: 'Notify',
+  data () {
+    return {
+      msgData: []
+    }
+  },
+  computed: {
+    title () {
+      if (this.msgData.length > 5) {
+        return `预警消息 (${this.msgData.length})`
+      }
+      return '预警消息'
+    },
+    hasMsg () {
+      return this.msgData.length > 0
+    },
+    tableData () {
+      return this.msgData.slice(0, 5).map(msg => {
+        const { level } = msg
+        msg.color = AlarmColors[level] || AlarmColors[2]
+        return msg
+      })
+    }
+  },
+  mounted () {
+    this.startMonitor()
+  },
+  beforeDestroy () {
+    this.stopMonitor()
+  },
+  methods: {
+    startMonitor () {
+      console.log('start dashboard monitor')
+      subscribe(['dashboard/event'], this.onMessage)
+    },
+    stopMonitor () {
+      console.log('stop dashboard monitor')
+      unsubscribe(['dashboard/event'], this.onMessage)
+    },
+    onMessage (topic, message) {
+      if (topic === 'dashboard/event') {
+        this.msgData.unshift(JSON.parse(message))
+      }
+    },
+    onClear () {
+      this.msgData = []
+    },
+    delateRowMsg (row) {
+      this.msgData.splice(row.$index, 1)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.c-notify {
+  position: fixed;
+  display: flex;
+  width: 300px;
+  right: $spacing;
+  bottom: $spacing;
+  z-index: 99;
+  overflow: hidden;
+  text-overflow: ellipsis;
+
+  ::v-deep .el-table {
+    border-radius: 8px;
+    box-shadow: 10px rgba(0, 0, 0, 0.25);
+
+    &__cell {
+      padding: 4px 0;
+    }
+
+    .notify-column .cell {
+      padding-right: 0;
+    }
+
+    .cell {
+      font-size: $font-size--sm;
+    }
+
+    th.el-table__cell {
+      color: white;
+      font-size: $font-size;
+      background-color: #1c5cb0;
+    }
+  }
+}
+</style>

+ 4 - 1
src/layout/index.vue

@@ -5,6 +5,7 @@
       <navbar class="l-flex__none" />
       <app-main class="l-flex__fill" />
     </div>
+    <notify />
   </div>
 </template>
 
@@ -12,13 +13,15 @@
 import Sidebar from './components/Sidebar'
 import Navbar from './components/Navbar'
 import AppMain from './components/AppMain'
+import Notify from './components/Notify'
 
 export default {
   name: 'Layout',
   components: {
     Sidebar,
     Navbar,
-    AppMain
+    AppMain,
+    Notify
   }
 }
 </script>

+ 0 - 44
src/permission.js

@@ -3,11 +3,6 @@ import store from './store'
 import NProgress from 'nprogress' // progress bar
 import 'nprogress/nprogress.css' // progress bar style
 import { cancelRequest } from './utils/request'
-import {
-  subscribe,
-  unsubscribe
-} from './utils/mqtt'
-import { Notification } from 'element-ui'
 
 NProgress.configure({ showSpinner: false }) // NProgress Configuration
 
@@ -20,20 +15,16 @@ router.beforeEach((to, from, next) => {
 
   if (store.getters.isValid) {
     if (to.path === '/error') {
-      startMonitor()
       // redirect to the home page
       next({ path: '/' })
       NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
     } else {
-      to?.meta?.dashboard ? stopMonitor() : startMonitor()
       next()
     }
   } else if (whiteList.includes(to.path)) {
-    to?.meta?.dashboard ? stopMonitor() : startMonitor()
     // in the free login whitelist, go directly
     next()
   } else {
-    stopMonitor()
     // other pages that do not have permission to access are redirected to the login page.
     next('/error')
     NProgress.done()
@@ -44,38 +35,3 @@ router.afterEach(() => {
   // finish progress bar
   NProgress.done()
 })
-
-let notify = false
-
-function startMonitor () {
-  if (notify) {
-    return
-  }
-  console.log('start monitor')
-  notify = true
-  subscribe(['dashboard/event'], onMessage)
-}
-
-function stopMonitor () {
-  if (!notify) {
-    return
-  }
-  console.log('stop monitor')
-  notify = false
-  unsubscribe(['dashboard/event'], onMessage)
-}
-
-function onMessage (topic, message) {
-  if (topic === 'dashboard/event') {
-    message = message && JSON.parse(message)
-    if (message.level > 1) {
-      Notification({
-        type: 'warning',
-        position: 'bottom-right',
-        duration: 0,
-        title: '紧急告警',
-        message: `${message.deviceName} 于 ${message.happenTime} 发生 ${message.bugName}`
-      })
-    }
-  }
-}