Kaynağa Gözat

feat(dashboard): optimize player

Casper Dai 2 yıl önce
ebeveyn
işleme
f2e3b8dae6

+ 69 - 15
src/components/service/external/DevicePlayer/index.vue

@@ -82,7 +82,8 @@ import {
   authCode,
   getRecordConfig,
   addRecordConfig,
-  updateRecordConfig
+  updateRecordConfig,
+  getDevice
 } from '@/api/device'
 import { GATEWAY } from '@/constant'
 import playerMixin from '../player'
@@ -115,10 +116,19 @@ export default {
     device: {
       type: Object,
       required: true
+    },
+    checkOnline: {
+      type: [Boolean, String],
+      default: false
+    },
+    useInitial: {
+      type: [Boolean, String],
+      default: false
     }
   },
   data () {
     return {
+      online: false,
       floating: true,
       qualities: [
         { value: 'fff', label: '标清' },
@@ -132,7 +142,7 @@ export default {
     }
   },
   computed: {
-    online () {
+    deviceOnline () {
       return this.device.onlineStatus === 1
     },
     canPlay () {
@@ -140,14 +150,11 @@ export default {
     }
   },
   watch: {
-    online (val) {
-      if (val) {
-        this.$nextTick(this.createPlayer)
-      } else {
-        this.hideQualityMenu()
-        this.onVideoReset()
-        this.destroyPlayer()
+    deviceOnline (val) {
+      if (this.checkOnline) {
+        return
       }
+      this.updateOnlineStatus(val)
     },
     isFullscreen () {
       this.onMouseMove()
@@ -155,14 +162,18 @@ export default {
   },
   created () {
     this.$delayMoveTimer = -1
+    this.$checkTimer = -1
   },
   mounted () {
-    if (this.online) {
+    if (this.checkOnline && !this.useInitial) {
       this.createPlayer()
+    } else {
+      this.updateOnlineStatus(this.deviceOnline)
     }
   },
   beforeDestroy () {
     clearTimeout(this.$delayMoveTimer)
+    clearTimeout(this.$checkTimer)
     this.hideQualityMenu()
   },
   methods: {
@@ -197,7 +208,7 @@ export default {
             const key = Object.keys(Quality).find(key => Quality[key].frameRate === frameRate) || 'fff'
             this.quality = this.qualities.find(({ value }) => value === key) || this.qualities[0]
             this.recordConfig = data
-            this.createPlayer()
+            this.onCreatePlayer()
           } else {
             this.setRecordConfig(this.qualities[0])
           }
@@ -218,7 +229,8 @@ export default {
           this.loadingQuality = false
           this.quality = quality
           this.recordConfig = data
-          this.createPlayer()
+          this.releasePlayer()
+          this.onCreatePlayer()
         },
         () => {
           this.onVideoDestroyByError()
@@ -249,22 +261,60 @@ export default {
     },
     getAuthCode () {
       this.$playerInfo = null
-      authCode(this.recordConfig.stream).then(
+      authCode(this.recordConfig.stream, { custom: true }).then(
         ({ data }) => {
           this.$playerInfo = data
-          this.createPlayer()
+          this.onCreatePlayer()
         },
         () => {
           this.onVideoDestroyByError()
         }
       )
     },
+    updateOnlineStatus (online) {
+      this.online = online
+      if (online) {
+        this.$nextTick(this.onCreatePlayer)
+      } else {
+        this.hideQualityMenu()
+        this.onVideoReset()
+        this.destroyPlayer()
+        if (this.checkOnline) {
+          this.checkOnlineStatus(5000)
+        }
+      }
+    },
     createPlayer () {
       if (this.$timer === null) {
         return
       }
+      clearTimeout(this.$checkTimer)
       this.loading = true
-      clearTimeout(this.$timer)
+      if (this.checkOnline) {
+        getDevice(this.device.id, { custom: true }).then(
+          ({ data }) => {
+            if (this.$timer === null) {
+              return
+            }
+            if (data) {
+              this.updateOnlineStatus(data.onlineStatus === 1)
+            }
+          },
+          () => {
+            if (this.$timer === null) {
+              return
+            }
+            this.checkOnlineStatus(2000)
+          }
+        )
+      } else {
+        this.onCreatePlayer()
+      }
+    },
+    onCreatePlayer () {
+      if (this.$timer === null) {
+        return
+      }
       if (!this.recordConfig) {
         this.getRecordConfig()
         return
@@ -280,6 +330,10 @@ export default {
       // }
       // this.playUrl(`${GATEWAY}/live/${this.recordConfig.stream}.flv?vhost=${vhost}&authorization=${token}&timestamp=${timestamp}&expire=${expire}`)
       this.playUrl(`${GATEWAY}/live/${this.recordConfig.stream}.flv?vhost=__defaultVhost__`)
+    },
+    checkOnlineStatus (delay = 5000) {
+      clearTimeout(this.$checkTimer)
+      this.$checkTimer = setTimeout(this.createPlayer, delay + Math.random() * delay | 0)
     }
   }
 }

+ 9 - 5
src/components/service/external/camera/CameraPlayer/index.vue

@@ -51,7 +51,7 @@
               v-for="item in videoSettings[settingActive.value]"
               :key="item.value"
               class="settingT settingsub"
-              @click="settingClick(item)"
+              @click="onSettingClick(item)"
             >
               <i :class="{ 'el-icon-check': item.active }" />
               {{ item.label }}
@@ -122,6 +122,10 @@ export default {
   computed: {
     ...mapGetters(['token'])
   },
+  created () {
+    this.$delayMoveTimer = -1
+    this.$checkTimer = -1
+  },
   mounted () {
     this.createPlayer()
   },
@@ -167,18 +171,18 @@ export default {
           } else {
             this.hideSettingsMenu()
             this.destroyPlayer()
-            this.checkOnline(5000)
+            this.checkOnlineStatus(5000)
           }
         },
         () => {
           if (this.$timer === null) {
             return
           }
-          this.checkOnline(2000)
+          this.checkOnlineStatus(2000)
         }
       )
     },
-    checkOnline (delay = 5000) {
+    checkOnlineStatus (delay = 5000) {
       clearTimeout(this.$checkTimer)
       this.$checkTimer = setTimeout(this.createPlayer, delay + Math.random() * delay | 0)
     },
@@ -304,7 +308,7 @@ export default {
         ]
       }
     },
-    settingClick (item) {
+    onSettingClick (item) {
       let value = null
       switch (this.settingActive.value) {
         case 'items':

+ 3 - 0
src/components/service/external/player.js

@@ -65,6 +65,9 @@ export default {
       // todo
     },
     onVideoProgress () {
+      if (this.paused || this.waiting) {
+        return
+      }
       const player = this.$refs.video
       if (player) {
         const end = player.buffered.end(0)

+ 4 - 5
src/router/index.js

@@ -619,15 +619,15 @@ export const asyncRoutes = [
   },
   {
     hidden: true,
+    name: 'devops',
     path: '/d/dashboard/devops',
-    component: () => import('@/views/dashboard/v1/index'),
-    meta: { dashboard: true }
+    component: () => import('@/views/dashboard/v1/index')
   },
   {
     hidden: true,
+    name: 'business',
     path: '/d/dashboard/business',
-    component: () => import('@/views/dashboard/v2/index'),
-    meta: { dashboard: true }
+    component: () => import('@/views/dashboard/v2/index')
   },
   {
     dev: !__DEVICE_DASHBARD__,
@@ -635,7 +635,6 @@ export const asyncRoutes = [
     name: 'device-dashboard',
     path: '/dm/dashboard/:id',
     component: () => import('@/views/device/detail/dashboard/index'),
-    meta: { dashboard: true },
     props: true
   },
   // 404 page must be placed at the end !!!

+ 1 - 1
src/views/dashboard/v1/FullScreen.vue

@@ -19,7 +19,7 @@ export default {
   name: 'FullScreen',
   data () {
     return {
-      isFullScreen: false
+      isFullScreen: !!this.$route.params.isFullScreen
     }
   },
   methods: {

+ 9 - 3
src/views/dashboard/v1/Header.vue

@@ -6,7 +6,10 @@
       <span>{{ date }}</span>
       <span class="time-week">{{ week }} </span>
       <span class="time-detail">{{ time }}</span>
-      <FullScreen class="time-full" />
+      <FullScreen
+        ref="fullscreen"
+        class="time-full"
+      />
     </div>
   </div>
 </template>
@@ -21,7 +24,7 @@ export default {
   },
   data () {
     return {
-      title: process.env.VUE_APP_NAME.replace('平台', '监看大屏'),
+      title: `${process.env.VUE_APP_NAME}监看大屏`,
       date: '',
       week: '',
       time: ''
@@ -35,6 +38,9 @@ export default {
     clearInterval(this.$timer)
   },
   methods: {
+    getFullScreen () {
+      return this.$refs.fullscreen.isFullScreen
+    },
     getCurrentTime () {
       const now = parseTime(new Date(), '{y}/{m}/{d} {h}:{i}:{s}').split(' ')
       this.date = now[0]
@@ -79,7 +85,7 @@ export default {
     margin-right: 85px;
   }
 
-  .time-full{
+  .time-full {
     font-size: 40px;
     transform: translateY(-4px);
   }

+ 12 - 2
src/views/dashboard/v1/Map.vue

@@ -1,6 +1,7 @@
 <template>
   <box class="map-box">
-    <div class="l-flex__fill l-flex--col device-map">
+    <div class="l-flex__fill l-flex--col u-relative">
+      <slot />
       <DeviceStatus
         :items="statusData"
         style="margin: 70px 0 40px"
@@ -249,7 +250,7 @@ export default {
         this.resetView()
       }
       /* 关闭标记点活跃 */
-      this.$alldeviceMap[alarm.deviceId]?.markObj?.setContent(
+      this.$alldeviceMap?.[alarm.deviceId]?.markObj?.setContent(
         this.getMarkerContent(
           this.$alldeviceMap[alarm.deviceId].onlineStatus,
           this.getMarkActive(alarm.deviceId)
@@ -441,6 +442,7 @@ export default {
   .amap-container {
     background: none !important;
   }
+
   ::v-deep {
     .c-marker {
       width: 14px;
@@ -450,12 +452,15 @@ export default {
       background-size: 100% 100%;
       background-position: center;
       position: relative;
+
       &.online {
         background-image: url("~@/assets/v1/icon_position1.svg");
       }
+
       &.offline {
         background-image: url("~@/assets/v1/icon_position2.svg");
       }
+
       &.active::before {
         // 阴影
         content: "";
@@ -468,6 +473,7 @@ export default {
         background-color: rgba(241, 34, 30, 0.9);
         animation: scale 2s infinite;
       }
+
       &.active::after {
         // 阴影
         content: "";
@@ -481,6 +487,7 @@ export default {
         animation: scale2 2s infinite;
       }
     }
+
     @keyframes scale {
       0% {
         transform: scale(1);
@@ -491,6 +498,7 @@ export default {
         opacity: 0;
       }
     }
+
     @keyframes scale2 {
       0% {
         transform: scale(1);
@@ -505,12 +513,14 @@ export default {
   .c-alarm {
     position: absolute;
     z-index: 99;
+
     &--sub {
       position: absolute;
       z-index: 9;
     }
   }
 }
+
 @keyframes sparkle {
   0% {
     opacity: 1;

+ 4 - 21
src/views/dashboard/v1/Record.vue

@@ -28,11 +28,13 @@
           @click="onToggleFullscreen(item)"
         />
         <device-player
+          :key="item.id"
           :device="item"
           controls
           autoplay
           retry
           keep
+          check-online
           @click="onClick(item)"
           @fullscreen="onToggleFullscreen(item)"
         >
@@ -60,13 +62,11 @@
 
 <script>
 import { getSensorRecords } from '@/api/external'
-import { getDevice } from '@/api/device'
 import { getSensorMap } from './api'
 import {
   createListOptions,
   parseTime
 } from '@/utils'
-import { Record } from './config'
 import Box from './Box'
 import TransferDeviceDialog from './TransferDeviceDialog'
 import { ThirdPartyDevice } from '@/constant'
@@ -84,10 +84,6 @@ export default {
       devices: JSON.parse(window.localStorage.getItem('MSR_DASHBOARD_DEVICES') || '[]').map(this.transformDevice)
     }
   },
-  created () {
-    this.checkDevices()
-    this.$timer = setInterval(this.checkDevices, Record.timer)
-  },
   beforeDestroy () {
     clearInterval(this.$timer)
   },
@@ -95,24 +91,11 @@ export default {
     transformDevice ({ id, name }) {
       return { id, name, onlineStatus: 0 }
     },
-    checkDevices () {
-      this.devices.forEach(item => {
-        getDevice(item.id).then(({ data }) => {
-          if (data) {
-            item.onlineStatus = data.onlineStatus
-            if (data.id === this.fullscreenId && data.onlineStatus !== 1) {
-              this.onToggleFullscreen(data)
-            }
-          }
-        })
-      })
-    },
     onChange (devices) {
       this.devices = devices.map(this.transformDevice)
-      this.checkDevices()
     },
-    onClick ({ onlineStatus, id }) {
-      if (onlineStatus && this.fullscreenId !== id) {
+    onClick ({ id }) {
+      if (this.fullscreenId !== id) {
         this.fullscreenId = id
       }
     },

+ 13 - 1
src/views/dashboard/v1/TransferCameraDialog.vue

@@ -20,7 +20,7 @@
           <el-button
             type="primary"
             size="mini"
-            :disabled="!selectionVal.length"
+            :disabled="ignoreAdd"
             @click="onAdd"
           >
             <i class="el-icon-arrow-right" />
@@ -81,6 +81,15 @@ export default {
       }
     }
   },
+  computed: {
+    selectedCount () {
+      return this.cameras.length
+    },
+    ignoreAdd () {
+      const length = this.selectionVal.length
+      return length === 0 || length + this.selectedCount > 4
+    }
+  },
   methods: {
     show () {
       this.cameras = JSON.parse(window.localStorage.getItem('MSR_DASHBOARD_CAMERAS') || '[]')
@@ -92,6 +101,9 @@ export default {
       done()
     },
     selectable ({ identifier }) {
+      if (this.selectedCount >= 4) {
+        return false
+      }
       return !this.cameras.some(camera => camera.identifier === identifier)
     },
     onRowClick (row) {

+ 13 - 1
src/views/dashboard/v1/TransferDeviceDialog.vue

@@ -24,7 +24,7 @@
           <el-button
             type="primary"
             size="mini"
-            :disabled="!selectionVal.length"
+            :disabled="ignoreAdd"
             @click="onAdd"
           >
             <i class="el-icon-arrow-right" />
@@ -90,6 +90,15 @@ export default {
       }
     }
   },
+  computed: {
+    selectedCount () {
+      return this.devices.length
+    },
+    ignoreAdd () {
+      const length = this.selectionVal.length
+      return length === 0 || length + this.selectedCount > 4
+    }
+  },
   methods: {
     onGroupChanged (group) {
       this.$group = group
@@ -114,6 +123,9 @@ export default {
       done()
     },
     selectable ({ id }) {
+      if (this.selectedCount >= 4) {
+        return false
+      }
       return !this.devices.some(device => device.id === id)
     },
     onRowClick (row) {

+ 44 - 29
src/views/dashboard/v1/index.vue

@@ -20,12 +20,14 @@
         ref="departmentDrawer"
         @change="onGroupChanged"
       />
-      <Header>
+      <Header ref="Header">
         <template #content>
           <div
-            class="c-department-button u-pointer"
-            @click="$refs.departmentDrawer.show"
-          >{{ group.name }}</div>
+            class="c-monitor-dashboard__mode has-active"
+            @click="onClickBusiness"
+          >
+            切换为运营大数据
+          </div>
         </template>
       </Header>
       <NewNotice
@@ -85,7 +87,16 @@
                 :status-data="statusData"
                 :device-list="deviceList"
                 @closeAlarm="onCloseAlarm"
-              />
+              >
+                <template #default>
+                  <div
+                    class="c-department-button has-active"
+                    @click="onShowDepatment"
+                  >
+                    概况
+                  </div>
+                </template>
+              </Map>
             </div>
           </div>
           <div class="l-flex--col l-flex__none">
@@ -133,7 +144,6 @@
               </div>
             </div>
           </div>
-
           <div
             class="l-flex__none l-flex--col"
             style="width: 730px; height: 450px"
@@ -229,6 +239,7 @@ export default {
   mounted () {
     this.checkScale()
     window.addEventListener('resize', this.checkScale)
+    document.querySelector('body').setAttribute('version', '')
   },
   beforeDestroy () {
     clearInterval(this.$timer)
@@ -243,6 +254,9 @@ export default {
         this.getDeviceStatistics()
       }
     },
+    onShowDepatment () {
+      this.$refs.departmentDrawer.show()
+    },
     checkScale () {
       this.style = {
         transform: `scale(${window.innerWidth / 3840}, ${
@@ -280,7 +294,6 @@ export default {
         this.showNotice = true
         this.curNotice = alarm
         clearInterval(this.$newAlarmTimer)
-        document.querySelector('body').setAttribute('version', '')
         this.noticeCount = Index.noticeTimer / 1000
         this.$newAlarmTimer = setInterval(() => {
           this.noticeCount--
@@ -288,9 +301,6 @@ export default {
             this.showNotice = false
             this.noticeCount = 0
             clearInterval(this.$newAlarmTimer)
-            setTimeout(() => {
-              document.querySelector('body').setAttribute('version', __VERSION__)
-            }, 1000)
           }
         }, 1000)
       }
@@ -326,25 +336,16 @@ export default {
         this.deviceList = data
       })
     },
-    onDeviceOnline () {
-      // 立即更新
-      this.getDeviceStatistics()
-    },
-    onDeviceOffline (id) {
-      const index = this.deviceList.findIndex(i => i.id === id)
-      if (index > -1) {
-        if (this.deviceList[index].onlineStatus === 1) { // 设备在线 mqtt下线 先踢出去 等轮询接口更新 若离线 直接调接口更新
-          this.deviceList.splice(index, 1)
-          this.statusData[1].value--
-          this.statusData[2].value++
-          return
-        }
-      }
-      this.getDeviceStatistics()
+    onClickBusiness () {
+      this.$router.push({
+        name: 'business',
+        params: { isFullScreen: this.$refs.Header.getFullScreen() ? '1' : '' }
+      })
     }
   }
 }
 </script>
+
 <style lang="scss" scoped>
 .c-monitor-dashboard {
   height: 100%;
@@ -356,22 +357,34 @@ export default {
     background: url("~@/assets/v1/monitor_bg.png");
     transform-origin: left top;
   }
+
+  &__mode {
+    position: absolute;
+    left: 135px;
+    bottom: 10px;
+    font-size: 32px;
+    z-index: 999;
+  }
 }
+
 .dashboard-block {
   & ~ & {
     margin-top: 20px;
   }
 }
+
 .l-flex--row {
   & ~ & {
     margin-top: 20px;
   }
 }
+
 .l-flex--col {
   & ~ & {
     margin-left: 20px;
   }
 }
+
 .new-notice {
   position: fixed;
   bottom: 0;
@@ -381,16 +394,18 @@ export default {
   transition: all 1s;
   z-index: 999;
   transform: translateY(100%);
+
   &.active {
     transform: translateY(0);
   }
 }
-.c-department-button{
+
+.c-department-button {
   position: absolute;
+  top: 0;
   left: 0;
-  z-index: 999;
-  bottom:10px;
   font-size: 32px;
-  left: 135px;
+  line-height: 64px;
+  z-index: 1;
 }
 </style>

+ 9 - 8
src/views/dashboard/v2/DeviceStatus.vue

@@ -1,5 +1,6 @@
 <template>
-  <div class="l-flex--col u-text--center has-content-padding o-device-status">
+  <div class="l-flex--col u-text--center has-content-padding o-device-status u-releative">
+    <slot />
     <video
       class="video"
       src="@/assets/map_1.mp4"
@@ -69,7 +70,7 @@ export default {
 }
 </script>
 <style lang="scss" scoped>
-.video{
+.video {
   position: absolute;
   left: 0;
   top: 0;
@@ -77,14 +78,14 @@ export default {
   height: 1237px;
   object-fit: cover;
 }
-.has-content-padding{
+.has-content-padding {
   padding: 0 24px 24px;
 }
 .o-device-status {
   position: relative;
   font-size: 36px;
   color: #fff;
-  &__ratio{
+  &__ratio {
     font-size: 96px;
     line-height: 110px;
     height: 930px;
@@ -98,20 +99,20 @@ export default {
   &_item {
     width: 33.3333%;
   }
-  &__num{
+  &__num {
     font-size: 64px;
     line-height: 100px;
     color: #f7d308;
   }
-  &__padding{
+  &__padding {
     padding: 0 160px;
     z-index: 2;
   }
 }
-.date{
+.date {
   text-align: center;
   font-size: 32px;
-  color: #9EA9CD;
+  color: #9ea9cd;
   z-index: 2;
   margin-top: 30px;
 }

+ 58 - 0
src/views/dashboard/v2/FullScreen.vue

@@ -0,0 +1,58 @@
+<template>
+  <div>
+    <slot
+      name="trigger"
+      :is-full-screen="isFullScreen"
+    >
+      <div
+        class=" has-active"
+        @click="changeFullScreen"
+      >
+        {{ isFullScreen ? "退出" : "全屏" }}
+      </div>
+    </slot>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'FullScreen',
+  data () {
+    return {
+      isFullScreen: !!this.$route.params.isFullScreen
+    }
+  },
+  methods: {
+    changeFullScreen () {
+      const element = document.documentElement
+      // 如果是全屏状态
+      if (this.isFullScreen) {
+        // 如果浏览器有这个Function
+        if (document.exitFullscreen) {
+          document.exitFullscreen()
+        } else if (document.webkitCancelFullScreen) {
+          document.webkitCancelFullScreen()
+        } else if (document.mozCancelFullScreen) {
+          document.mozCancelFullScreen()
+        } else if (document.msExitFullscreen) {
+          document.msExitFullscreen()
+        }
+      } else if (element.requestFullscreen) {
+        element.requestFullscreen()
+      } else if (element.webkitRequestFullScreen) {
+        element.webkitRequestFullScreen()
+      } else if (element.mozRequestFullScreen) {
+        element.mozRequestFullScreen()
+      } else if (element.msRequestFullscreen) {
+        element.msRequestFullscreen()
+      }
+      this.isFullScreen = !this.isFullScreen
+    }
+  }
+}
+</script>
+<style
+  lang="
+      scss"
+  scoped
+></style>

+ 23 - 7
src/views/dashboard/v2/Header.vue

@@ -6,17 +6,25 @@
       <span>{{ date }}</span>
       <span class="time-week">{{ week }} </span>
       <span class="time-detail">{{ time }}</span>
+      <FullScreen
+        ref="fullscreen"
+        class="time-full"
+      />
     </div>
   </div>
 </template>
 
 <script>
 import { parseTime } from '@/utils'
+import FullScreen from './FullScreen'
 
 export default {
+  components: {
+    FullScreen
+  },
   data () {
     return {
-      title: '浪潮屏媒安播云广告运营看板',
+      title: `${process.env.VUE_APP_NAME}广告运营看板`,
       date: '',
       week: '',
       time: ''
@@ -30,6 +38,9 @@ export default {
     clearInterval(this.$timer)
   },
   methods: {
+    getFullScreen () {
+      return this.$refs.fullscreen.isFullScreen
+    },
     getCurrentTime () {
       const now = parseTime(new Date(), '{y}/{m}/{d} {h}:{i}:{s}').split(' ')
       this.date = now[0]
@@ -57,21 +68,26 @@ export default {
 
   &__time {
     display: flex;
-    align-items: flex-end;
+    align-items: center;
     position: absolute;
     right: 120px;
-    bottom: 40px;
-    font-size: 36px;
+    bottom: 34px;
+    font-size: 32px;
     line-height: 1;
   }
 
   .time-week {
-    margin: 0 64px;
+    margin: 0 50px 0 24px;
   }
 
   .time-detail {
-    font-size: 52px;
-    font-weight: bold;
+    font-size: 32px;
+    margin-right: 85px;
+  }
+
+  .time-full{
+    font-size: 40px;
+    transform: translateY(-4px);
   }
 }
 </style>

+ 46 - 23
src/views/dashboard/v2/index.vue

@@ -8,12 +8,14 @@
         ref="departmentDrawer"
         @change="onGroupChanged"
       />
-      <Header>
+      <Header ref="Header">
         <template #content>
           <div
-            class="c-department-button u-pointer"
-            @click="$refs.departmentDrawer.show"
-          >{{ group.name }}</div>
+            class="c-monitor-dashboard__mode has-active"
+            @click="onClickDevops"
+          >
+            切换为运维大数据
+          </div>
         </template>
       </Header>
       <div class="l-flex--col center">
@@ -47,7 +49,16 @@
               <DeviceStatus
                 :items="statusData"
                 :ratio="runRatio"
-              />
+              >
+                <template #default>
+                  <div
+                    class="c-department-button has-active"
+                    @click="onShowDepatment"
+                  >
+                    概况
+                  </div>
+                </template>
+              </DeviceStatus>
             </div>
           </div>
           <div class="l-flex--col l-flex__none">
@@ -147,11 +158,13 @@ export default {
   mounted () {
     this.checkScale()
     window.addEventListener('resize', this.checkScale)
+    document.querySelector('body').setAttribute('version', '')
   },
   beforeDestroy () {
     clearInterval(this.$timer)
     clearInterval(this.$newAlarmTimer)
     window.removeEventListener('resize', this.checkScale)
+    document.querySelector('body').setAttribute('version', __VERSION__)
   },
   methods: {
     onGroupChanged ({ path, name }) {
@@ -160,6 +173,9 @@ export default {
         this.getDeviceStatistics()
       }
     },
+    onShowDepatment () {
+      this.$refs.departmentDrawer.show()
+    },
     checkScale () {
       this.style = {
         transform: `scale(${window.innerWidth / 3840}, ${
@@ -197,10 +213,17 @@ export default {
       ).then(({ data }) => {
         this.deviceList = data
       })
+    },
+    onClickDevops () {
+      this.$router.push({
+        name: 'devops',
+        params: { isFullScreen: this.$refs.Header.getFullScreen() ? '1' : '' }
+      })
     }
   }
 }
 </script>
+
 <style lang="scss" scoped>
 .c-monitor-dashboard {
   height: 100%;
@@ -212,41 +235,41 @@ export default {
     background: url("~@/assets/v1/monitor_bg.png");
     transform-origin: left top;
   }
+
+  &__mode {
+    position: absolute;
+    left: 135px;
+    bottom: 10px;
+    font-size: 32px;
+    z-index: 999;
+  }
 }
+
 .dashboard-block {
   & ~ & {
     margin-top: 20px;
   }
 }
+
 .l-flex--row {
   & ~ & {
     margin-top: 20px;
   }
 }
+
 .l-flex--col {
   & ~ & {
     margin-left: 20px;
   }
 }
-.new-notice {
-  position: fixed;
-  bottom: 0;
-  right: 0;
-  width: 640px;
-  height: 360px;
-  transition: all 1s;
-  z-index: 999;
-  transform: translateY(360px);
-  &.active {
-    transform: translateY(0);
-  }
-}
-.c-department-button{
+
+.c-department-button {
   position: absolute;
-  left: 0;
-  z-index: 999;
-  bottom:10px;
+  top: 0;
+  left: 24px;
   font-size: 38px;
-  left: 135px;
+  line-height: 80px;
+  font-weight: bold;
+  z-index: 1;
 }
 </style>

+ 6 - 0
src/views/device/record/index.vue

@@ -12,8 +12,14 @@
     >
       <grid-table-item v-slot="item">
         <device-player
+          :key="item.id"
           :device="item"
           controls
+          autoplay
+          retry
+          keep
+          check-online
+          use-initial
         />
       </grid-table-item>
     </grid-table>