Преглед изворни кода

refactor(dashboard): v1 v2

Casper Dai пре 2 година
родитељ
комит
17ddcceab5

BIN
src/assets/v2/map.png


+ 4 - 4
src/views/dashboard/Dashboard.vue

@@ -51,7 +51,7 @@
         @click="onRefresh"
       />
     </div>
-    <div
+    <!-- <div
       v-if="__PLACEHOLDER__"
       class="l-flex__none c-sibling-item--v far c-cards"
     >
@@ -87,7 +87,7 @@
         title="即将空闲排期"
         count="100"
       />
-    </div>
+    </div> -->
     <div
       ref="deviceContainer"
       class="l-flex__auto l-grid--info c-sibling-item--v far u-overflow-y--auto"
@@ -130,13 +130,13 @@ import {
   getDeviceStatisticsByPath,
   getStatusReport
 } from '@/api/device'
-import Card from './components/Card'
+// import Card from './components/Card'
 import Device from './components/Device'
 
 export default {
   name: 'Dashboard',
   components: {
-    Card,
+    // Card,
     Device
   },
   data () {

+ 27 - 12
src/views/dashboard/v1/AlarmInfo.vue

@@ -7,12 +7,6 @@
         class="el-icon-error u-pointer"
         @click="close"
       /></div>
-      {{ alarm.deviceName }}
-    </div>
-    <div
-      class="l-flex--row center"
-      :style="colorStyle"
-    >
       <svg-icon
         class="alarm__icon"
         icon-class="v0-alarm"
@@ -20,6 +14,13 @@
       <div class="alarm__name">
         {{ levelMap[alarm.level] }}
       </div>
+
+    </div>
+    <div
+      class="l-flex--row center alarm__second"
+      :style="colorStyle"
+    >
+      {{ alarm.deviceName }}
     </div>
     <div class="l-flex--row center alarm__type u-text--center">
       <!-- <auto-text
@@ -108,12 +109,20 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+@keyframes animated-border {
+    0% {
+    box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.4);
+    }
+    100% {
+    box-shadow: 0px 0px 40px 0px rgba(244, 6, 69, 1);
+}
+}
 .info {
   color: #f40645;
   &__bg {
     width: 640px;
     border: 3px solid rgba(244, 6, 69, 1);
-    background-color: rgba(65, 4, 20, 0.63);
+    background-color: rgba(65, 4, 20, 1);
     box-shadow: 0px 0px 40px 0px rgba(244, 6, 69, 1);
     min-height: 320px;
     padding-bottom: 20px;
@@ -122,14 +131,16 @@ export default {
     height: 40px;
     opacity: 0.5;
     font-size: 16px;
-    background: rgba(#7b102c, 0.5);
+    background: rgba(#7b102c, 0.8);
     margin: 0 16px;
     .row__label {
-      color: #9ea9cd;
+      color: #fff;
+      font-weight: bold;
       width: 150px;
     }
     .row__value {
       color: #fff;
+      font-weight: bold;
     }
   }
 
@@ -150,16 +161,20 @@ export default {
   }
   .alarm {
     &__icon {
-      width: 24px;
-      height: 24px;
+      width: 32px;
+      height: 32px;
       background-repeat: no-repeat;
       background-size: 100%;
+      transform: translate(-4px,-4px);
     }
     &__name {
-      font-size: 24px;
+      font-size: 32px;
       line-height: 36px;
       font-weight: 500;
     }
+    &__second{
+      font-size: 28px;
+    }
     &__type {
       font-size: 32px;
       padding: 0 10px;

+ 86 - 8
src/views/dashboard/v1/CameraScreen.vue

@@ -4,14 +4,38 @@
       v-if="options.list.length"
       class="l-flex__auto c-record-grid"
     >
-      <camera-player
-        v-for="camera in options.list"
-        :key="camera.id"
-        :camera="camera"
-        autoplay
-        retry
-        keep
-      />
+      <div
+        v-for="item in options.list"
+        :key="item.id"
+        :class="{fullscreen:item.id===fullscreenId}"
+        class="c-record-wrapper"
+      >
+        <i
+          v-if="item.id===fullscreenId"
+          class="el-icon-circle-close c-record-close has-active"
+          @click="fullscreenId=''"
+        />
+        <camera-player
+          :camera="item"
+          autoplay
+          retry
+          keep
+        >
+          <!-- <template #default>
+            <i
+              v-if="item.id!==fullscreenId&&item.onlineStatus===1"
+              class="c-sibling-item el-icon-full-screen has-active c-record-full-screen"
+              @click="onFullScreen(item.id)"
+            />
+
+          </template> -->
+        </camera-player>
+        <i
+          v-if="item.id!==fullscreenId&&item.onlineStatus===1"
+          class="c-sibling-item el-icon-full-screen has-active c-record-full-screen"
+          @click="onFullScreen(item.id)"
+        />
+      </div>
     </div>
     <div
       v-else
@@ -34,6 +58,7 @@ export default {
   },
   data () {
     return {
+      fullscreenId: '',
       options: createListOptions({ pageSize: 40 })
     }
   },
@@ -45,9 +70,17 @@ export default {
     this.$timer = -1
   },
   methods: {
+    onFullScreen (id) {
+      if (this.fullscreenId === id) {
+        this.fullscreenId = ''
+      } else {
+        this.fullscreenId = id
+      }
+    },
     getCameras () {
       getCameras(this.options.params).then(
         ({ data }) => {
+          data.sort((a, b) => (a.onlineStatus === 1 && b.onlineStatus !== 1) ? -1 : 1)
           if (data.length <= 4) {
             this.options.list = data
           } else {
@@ -89,4 +122,49 @@ export default {
   grid-row-gap: 20px;
   grid-column-gap: 20px;
 }
+.c-record-close{
+  font-size: 64px;
+  position: absolute;
+  top: -60px;
+  right: -60px;
+}
+.c-record-wrapper{
+  position: relative;
+  .c-record-full-screen{
+    position: absolute;
+    right:  16px;
+    bottom: 24px ;
+    display: none;
+  }
+  &:hover{
+    .c-record-full-screen{
+    display: block;
+    }
+  }
+}
+.fullscreen.c-record-wrapper {
+  position: fixed;
+  width: 3072px;
+  height: 1728px;
+  top: 50%;
+  left: 50%;
+  border-bottom: none;
+  transform: translate(-50%, -50%);
+  overflow: visible;
+  z-index: 999;
+
+  &::before {
+    content: "";
+    position: absolute;
+    top: -216px;
+    left: -384px;
+    width: 3840px;
+    height: 2160px;
+    background-color: rgba(#000, 0.6);
+    z-index: -1;
+  }
+  ::v-deep.c-footer{
+    font-size: 56px;
+  }
+}
 </style>

+ 19 - 9
src/views/dashboard/v1/Map.vue

@@ -228,6 +228,16 @@ export default {
     onAlarmClose (index) {
       this.alarmList.splice(index, 1)
     },
+    closeOfflineAlarm (alarm, offlineMap) {
+      if (offlineMap.includes(this.alarm.deviceErrorId) && this.alarm.deviceId === alarm.deviceId) {
+        this.isShowAlarm = false
+        return
+      }
+      const index = this.alarmList.findIndex(i => offlineMap.includes(i.deviceErrorId) && i.deviceId === alarm.deviceId)
+      if (index > -1) {
+        this.alarmList.splice(index, 1)
+      }
+    },
     setNewAlarm (alarm) {
       const {
         markObj: marker,
@@ -235,21 +245,22 @@ export default {
         address
       } = this.$alldeviceMap?.[alarm.deviceId] || {}
       alarm = { ...alarm, mac, address, status: alarm.status.label }
-      if (!marker) { // 没有经纬度 周围展示
+      if (!marker) { // 没有经纬度 周围展示不移动
         this.alarmList.unshift(alarm)
+        this.subAlarmShow = true
         return
       }
-      if (this.isShowAlarm) { // 有中间占位警告 将当前中间的四周展示
+      if (this.isShowAlarm || this.isMoving) { // 有中间占位警告 将当前中间的四周展示   或者是正在移动的警告
         this.alarmList.unshift(this.alarm)
       }
       // 中间展示
       this.alarm = alarm
-
-      //
+      // 移动逻辑
       this.map.on('zoomend', this.onSetNewAlarmFitView)
       this.map.on('moveend', this.onSetNewAlarmFitView)
       this.isShowAlarm = false
       this.subAlarmShow = false
+      this.isMoving = true // 防止间隔过短的警告
       this.$mapMoveTimer = setTimeout(() => { // 还是当前地点没有动地图
         this.onSetNewAlarmFitView()
       }, 1000)
@@ -262,14 +273,12 @@ export default {
     },
     onSetNewAlarmFitView () {
       clearTimeout(this.$mapMoveTimer)
+      this.map.off('zoomend', this.onSetNewAlarmFitView)
+      this.map.off('moveend', this.onSetNewAlarmFitView)
+      // 移动完毕,清除移动监听 设置弹出框状态
       this.showAlarm(this.curMarker._points)
     },
     showAlarm (position) {
-      this.map.off('zoomend', this.onSetNewAlarmFitView)
-      this.map.off('moveend', this.onSetNewAlarmFitView)
-
-      // const y = this.$refs.map.offsetHeight
-
       const width = 700 / 2
       const height = 420
       let left = position[0]
@@ -301,6 +310,7 @@ export default {
       this.alarmPosition = [`${left}px`, `${top}px`]
       this.isShowAlarm = true
       this.subAlarmShow = true
+      this.isMoving = false
     },
     refreshMarkers () {
       const map = {}

+ 248 - 14
src/views/dashboard/v1/MessageNotice.vue

@@ -144,10 +144,7 @@ export default {
   methods: {
     onMessage (topic, payload) {
       if (topic !== 'dashboard/event') { return }
-      if (typeof payload === 'string') {
-        payload = JSON.parse(payload)
-      }
-      payload.deviceId += ''
+      payload = payload && JSON.parse(payload)
       console.log(`%c大屏dashboard/event`, 'color: red')
       console.log(payload)
       const alarm = {
@@ -160,19 +157,14 @@ export default {
         handle: '未干预',
         status: {
           label: '-'
-        }
+        },
+        deviceErrorId: +payload.deviceErrorId
       }
-      if (alarm.level === 2) {
+      if (alarm.level > 1) {
         this.newAlarmList.unshift(alarm)
       }
       this.listData.unshift(alarm)
       this.$emit('new-alarm', { ...alarm })
-      if (alarm.type.match(RegExp(/播控器离线/))) {
-        this.$emit('deviceOffline', alarm.deviceId)
-      }
-      if (alarm.type.match(RegExp(/播控器上线/))) {
-        this.$emit('deviceOnline', alarm.deviceId)
-      }
     },
     getDeviceAlarms () {
       getDeviceAlarms(
@@ -246,12 +238,254 @@ export default {
   }
 
   &__newList {
-    animation: sparkle 8s linear infinite;
+    // animation: sparkle 8s linear infinite;
+    overflow: hidden;
+    position: relative;
+    animation: liuguang 2s infinite linear;
+    &::before {
+      position: absolute;
+      z-index: 1;
+      content: "";
+      top: 0;
+      left: 0;
+      width: 64px;
+      height: 100%;
+      background: linear-gradient(
+        to right,
+        rgba(255, 255, 255, 0),
+        white,
+        rgba(255, 255, 255, 0)
+      );
+      transform: scaleY(1.5) skewX(-30deg) rotateZ(0);
+      animation: shining-line-move 2s ease-in-out infinite;
+      opacity: 0.8;
+      filter: blur(4px);
+    }
     &:hover {
-      animation: none;
+      // animation: none;
     }
   }
+  --color1: #b721ff;
+  --color2: #21d4fd;
+  @keyframes liuguang {
+    0% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) 0%,
+        var(--color2) 100%,
+        var(--color1) 200%,
+        var(--color2) 300%
+      );
+    }
+
+    5% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -10%,
+        var(--color2) 90%,
+        var(--color1) 190%,
+        var(--color2) 290%
+      );
+    }
+
+    10% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -20%,
+        var(--color2) 80%,
+        var(--color1) 180%,
+        var(--color2) 280%
+      );
+    }
+
+    15% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -30%,
+        var(--color2) 70%,
+        var(--color1) 170%,
+        var(--color2) 270%
+      );
+    }
+
+    20% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -40%,
+        var(--color2) 60%,
+        var(--color1) 160%,
+        var(--color2) 260%
+      );
+    }
+
+    25% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -50%,
+        var(--color2) 50%,
+        var(--color1) 150%,
+        var(--color2) 250%
+      );
+    }
+
+    30% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -60%,
+        var(--color2) 40%,
+        var(--color1) 140%,
+        var(--color2) 240%
+      );
+    }
+
+    35% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -70%,
+        var(--color2) 30%,
+        var(--color1) 130%,
+        var(--color2) 230%
+      );
+    }
+
+    40% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -80%,
+        var(--color2) 20%,
+        var(--color1) 120%,
+        var(--color2) 220%
+      );
+    }
+
+    45% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -90%,
+        var(--color2) 10%,
+        var(--color1) 110%,
+        var(--color2) 210%
+      );
+    }
+
+    50% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -100%,
+        var(--color2) 0%,
+        var(--color1) 100%,
+        var(--color2) 200%
+      );
+    }
+
+    55% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -110%,
+        var(--color2) -10%,
+        var(--color1) 90%,
+        var(--color2) 190%
+      );
+    }
+
+    60% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -120%,
+        var(--color2) -20%,
+        var(--color1) 80%,
+        var(--color2) 180%
+      );
+    }
 
+    65% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -130%,
+        var(--color2) -30%,
+        var(--color1) 70%,
+        var(--color2) 170%
+      );
+    }
+
+    70% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -140%,
+        var(--color2) -40%,
+        var(--color1) 60%,
+        var(--color2) 160%
+      );
+    }
+
+    75% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -150%,
+        var(--color2) -50%,
+        var(--color1) 50%,
+        var(--color2) 150%
+      );
+    }
+
+    80% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -160%,
+        var(--color2) -60%,
+        var(--color1) 40%,
+        var(--color2) 140%
+      );
+    }
+
+    85% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -170%,
+        var(--color2) -70%,
+        var(--color1) 30%,
+        var(--color2) 130%
+      );
+    }
+
+    90% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -180%,
+        var(--color2) -80%,
+        var(--color1) 20%,
+        var(--color2) 120%
+      );
+    }
+
+    95% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -190%,
+        var(--color2) -90%,
+        var(--color1) 10%,
+        var(--color2) 110%
+      );
+    }
+
+    100% {
+      background: linear-gradient(
+        to bottom right,
+        var(--color1) -200%,
+        var(--color2) -100%,
+        var(--color1) 0%,
+        var(--color2) 100%
+      );
+    }
+  }
+  @keyframes shining-line-move {
+    from {
+      left: -20%;
+    }
+    to {
+      left: 120%;
+    }
+  }
   @keyframes sparkle {
     0% {
       opacity: 1;

+ 2 - 3
src/views/dashboard/v1/NewNotice.vue

@@ -5,7 +5,7 @@
       <div class="l-flex__none c-count">{{ count }}s</div>
     </div>
     <div class="c-block l-flex--col jcenter center l-flex__auto has-padding">
-      <div class="c-block--time">{{ notice.happenTime }}</div>
+      <div class="c-block--time u-bold">{{ notice.happenTime }}</div>
       <div class="c-block--info u-bold u-text--center">{{ notice.deviceName }}{{ notice.type }}</div>
     </div>
   </div>
@@ -43,8 +43,7 @@ export default {
 .c-block {
   background: #fff;
   &--time {
-    font-weight: 400;
-    color: #cacaca;
+    color: #6a6565;
     margin-bottom:30px ;
   }
   &--info {

+ 81 - 12
src/views/dashboard/v1/Record.vue

@@ -4,16 +4,25 @@
       v-if="options.list.length"
       class="l-flex__auto c-record-grid"
     >
-      <device-player
+      <div
         v-for="item in options.list"
-        :key="item.identifier"
-        :device="item"
-        controls
-        autoplay
-        retry
-        keep
+        :key="item.id"
+        :class="{fullscreen:item.id===fullscreenId}"
+        class="c-record-wrapper"
       >
-        <!-- <template #header>
+        <i
+          v-if="item.id===fullscreenId"
+          class="el-icon-circle-close c-record-close has-active"
+          @click="fullscreenId=''"
+        />
+        <device-player
+          :device="item"
+          controls
+          autoplay
+          retry
+          keep
+        >
+          <!-- <template #header>
           <div class="l-flex--row l-flex__fill">
             <div class="l-flex__fill u-ellipsis">
               温度: {{ item.temperature || '-' }}
@@ -23,10 +32,20 @@
             </div>
           </div>
         </template> -->
-        <template #controls="{ waitingOrLoading, online, isPlaying }">
-          <img :src="getStatusIcon(waitingOrLoading, online, isPlaying)">
-        </template>
-      </device-player>
+          <template #controls="{ waitingOrLoading, online, isPlaying }">
+            <i
+              v-if="item.id!==fullscreenId&&item.onlineStatus===1"
+              class="c-sibling-item el-icon-full-screen has-active c-record-full-screen"
+              @click="onFullScreen(item.id)"
+            />
+            <img
+              v-if="item.id!==fullscreenId"
+              class="c-sibling-item"
+              :src="getStatusIcon(waitingOrLoading, online, isPlaying)"
+            >
+          </template>
+        </device-player>
+      </div>
     </div>
     <div
       v-else
@@ -59,6 +78,7 @@ export default {
   },
   data () {
     return {
+      fullscreenId: '',
       options: createListOptions({ activate: 1, pageSize: 4 })
     }
   },
@@ -70,6 +90,13 @@ export default {
     clearInterval(this.$timer)
   },
   methods: {
+    onFullScreen (id) {
+      if (this.fullscreenId === id) {
+        this.fullscreenId = ''
+      } else {
+        this.fullscreenId = id
+      }
+    },
     transfromData (data) {
       const map = {}
       const arr = []
@@ -129,6 +156,7 @@ export default {
     },
     getDevices () {
       getDeviceAttentionList(this.options.params, { custom: true }).then(({ data }) => {
+        data.sort((a, b) => (a.onlineStatus === 1 && b.onlineStatus !== 1) ? -1 : 1)
         if (this.options.list.length) {
           this.updateDevices(data)
         }
@@ -230,4 +258,45 @@ export default {
   grid-row-gap: 20px;
   grid-column-gap: 20px;
 }
+.c-record-close{
+  font-size: 64px;
+  position: absolute;
+  top: -60px;
+  right: -60px;
+}
+.c-record-wrapper{
+  .c-record-full-screen{
+    display: none;
+  }
+  &:hover{
+    .c-record-full-screen{
+    display: block;
+    }
+  }
+}
+.fullscreen {
+  position: fixed;
+  width: 3072px;
+  height: 1728px;
+  top: 50%;
+  left: 50%;
+  border-bottom: none;
+  transform: translate(-50%, -50%);
+  overflow: visible;
+  z-index: 999;
+
+  &::before {
+    content: "";
+    position: absolute;
+    top: -216px;
+    left: -384px;
+    width: 3840px;
+    height: 2160px;
+    background-color: rgba(#000, 0.6);
+    z-index: -1;
+  }
+  ::v-deep.c-footer{
+    font-size: 56px;
+  }
+}
 </style>

+ 16 - 4
src/views/dashboard/v1/index.vue

@@ -43,8 +43,6 @@
             >
               <MessageNotice
                 @new-alarm="onNewAlarm"
-                @deviceOffline="onDeviceOffline"
-                @deviceOnline="onDeviceOnline"
               />
             </div>
             <div class="l-flex__none dashboard-block l-flex--row">
@@ -233,6 +231,7 @@ export default {
     clearInterval(this.$timer)
     clearInterval(this.$newAlarmTimer)
     window.removeEventListener('resize', this.checkScale)
+    document.querySelector('body').setAttribute('version', __VERSION__)
   },
   methods: {
     onGroupChanged ({ path, name }) {
@@ -257,7 +256,17 @@ export default {
       audio.play()
     },
     onNewAlarm (alarm) {
-      if (alarm.level === 2) {
+      const onlineMap = [32, 9]
+      const offlineMap = [1, 15, 16, 17]
+      if (onlineMap.includes(alarm.deviceErrorId)) {
+        this.getDeviceStatistics()
+        this.$refs.map?.closeOfflineAlarm(alarm, offlineMap)
+      }
+      if (offlineMap.includes(alarm.deviceErrorId)) {
+        this.getDeviceStatistics()
+      }
+
+      if (alarm.level > 1) {
         this.$refs.map?.setNewAlarm(alarm)
         this.playAlarm('alarmUrgent')
       } else {
@@ -265,7 +274,7 @@ 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--
@@ -273,6 +282,9 @@ export default {
             this.showNotice = false
             this.noticeCount = 0
             clearInterval(this.$newAlarmTimer)
+            setTimeout(() => {
+              document.querySelector('body').setAttribute('version', __VERSION__)
+            }, 1000)
           }
         }, 1000)
       }

+ 0 - 154
src/views/dashboard/v2/AlarmInfo.vue

@@ -1,154 +0,0 @@
-<template>
-  <div class="info__bg l-flex--col  center jcenter ">
-    <div class="info">
-      <div class="l-flex--row center info__deviceName">
-        {{ alarm.deviceName }}
-      </div>
-      <div
-        class="l-flex--row center"
-        :style="colorStyle"
-      >
-        <svg-icon
-          class="alarm__icon"
-          icon-class="v0-alarm"
-        />
-        <div class="alarm__name">
-          {{ levelMap[alarm.level] }}
-        </div>
-      </div>
-      <div class="l-flex--row center alarm__type">
-        {{ alarm.type }}
-      </div>
-      <div
-        v-for="(row, index) in rows"
-        :key="index"
-        class="l-flex--row info__row c-sibling-item--v far"
-      >
-        <div
-          v-for="item in row"
-          :key="item.key"
-          class="l-flex--row l-flex__fill"
-        >
-          <div class="l-flex__none l-flex--row center row__label">
-            {{ item.label }}
-          </div>
-          <div class="l-flex__fill row__value">
-            {{ alarm[item.key] }}
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'AlarmInfo',
-  components: {},
-  props: {
-    alarm: {
-      type: Object,
-      required: true
-    }
-  },
-  data () {
-    return {
-      levelMap: ['普通等级', '提示等级', '紧急等级'],
-      rows: [
-        [
-          {
-            label: '发生时间',
-            key: 'happenTime'
-          },
-          {
-            label: 'MAC',
-            key: 'mac'
-          }
-        ],
-        [
-          {
-            label: '系统配置预处理方式',
-            key: 'handle'
-          },
-          {
-            label: '执行结果',
-            key: 'status'
-          }
-        ],
-        [
-          {
-            label: '位置',
-            key: 'address'
-          }
-        ]
-      ]
-    }
-  },
-  methods: {
-    colorStyle () {
-      return this.alarm
-        ? {
-          color: ['#04A681', '#FFA000', '#F40645'][this.alarm.level]
-        }
-        : null
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.info {
-  color: #f40645;
-  width: 640px;
-  height: 360px;
-  &__bg {
-    width: 720px;
-    height: 440px;
-    background: url("~@/assets/v1/bg_alarm.png");
-    background-size: 100%;
-    background-position: center;
-    background-repeat: no-repeat;
-  }
-  &__row {
-    height: 40px;
-    opacity: 0.5;
-    font-size: 16px;
-    background: rgba(#7b102c, 0.5);
-    margin: 0 16px;
-    .row__label {
-      color: #9ea9cd;
-      width: 150px;
-    }
-    .row__value {
-      color: #fff;
-    }
-  }
-
-  &__deviceName {
-    line-height: 48px;
-    font-size: 32px;
-    font-weight: bold;
-    margin: 20px 0 15px 0;
-  }
-  .alarm {
-    &__icon {
-      width: 24px;
-      height: 24px;
-      background-repeat: no-repeat;
-      background-size: 100%;
-    }
-    &__name {
-      font-size: 30px;
-      line-height: 36px;
-      font-weight: 500;
-    }
-    &__type {
-      font-size: 32px;
-      padding: 0 10px;
-      line-height: 48px;
-      font-weight: bold;
-      margin: 15px 0 15px 0;
-    }
-  }
-}
-</style>

+ 0 - 109
src/views/dashboard/v2/LineChart.vue

@@ -1,109 +0,0 @@
-<template>
-  <div ref="canvas" />
-</template>
-
-<script>
-import * as echarts from 'echarts'
-
-export default {
-  name: 'LineChart',
-  props: {
-    list: {
-      type: Array,
-      default: () => []
-    },
-    colorType: {
-      type: Number,
-      default: 0
-    },
-    unit: {
-      type: String,
-      default: '%'
-    }
-  },
-  data () {
-    return {
-      colorMap: [
-        ['rgb(0, 209, 255)', 'rgba(0,209,255,0.5)'],
-        [' rgb(243,13,255)', ' rgba(243,13,255,0.5)'],
-        ['rgba(255,96,0)', 'rgba(255,96,0,0.5)'],
-        ['rgba(4,255,152)', 'rgba(4,255,152,0.5)']
-      ]
-    }
-  },
-  watch: {
-    list () {
-      this.renderChart(true)
-    }
-  },
-  mounted () {
-    this.init()
-  },
-  methods: {
-    renderChart (type) {
-      if (!this.$echarts || !this.list.length) {
-        return
-      }
-
-      this.$echarts.setOption(
-        {
-          xAxis: {
-            type: 'category',
-            show: false,
-            boundaryGap: false
-          },
-          yAxis: {
-            type: 'value',
-            show: false
-          },
-          title: {
-            text: `${Math.floor(+this.list[this.list.length - 1][1])}${this.unit}`,
-            top: 'center',
-            right: '0',
-            textStyle: {
-              color: '#fff',
-              fontSize: 18
-            }
-          },
-
-          grid: {
-            right: this.unit === '%' ? '35%' : '50%'
-          },
-
-          series: [
-            {
-              data: this.list,
-              type: 'line',
-              smooth: true,
-              symbol: 'none',
-              lineStyle: {
-                color: this.colorMap[this.colorType][0]
-              },
-              areaStyle: {
-                color: echarts.graphic.LinearGradient(0, 0, 0, 1, [
-                  {
-                    offset: 0,
-                    color: this.colorMap[this.colorType][1]
-                  },
-                  {
-                    offset: 1,
-                    color: 'rgba(33,190,230,0)'
-                  }
-                ])
-              }
-            }
-          ]
-        },
-        type
-      )
-    },
-    init () {
-      if (!this.$echarts) {
-        this.$echarts = echarts.init(this.$refs.canvas)
-      }
-      this.renderChart()
-    }
-  }
-}
-</script>
-<style lang="scss" scoped></style>

+ 0 - 232
src/views/dashboard/v2/SystemLoad.vue

@@ -1,232 +0,0 @@
-<template>
-  <Box title="系统实时负载">
-    <div class="l-flex__fill l-flex--col c-load">
-      <div class="l-flex c-duration u-bold">
-        系统运行时长<span class="c-duration__num">{{ diffDay }}</span>天
-      </div>
-      <div class="l-flex__none l-flex--row c-load__header">
-        <div class="l-flex__fill">服务器</div>
-        <div class="l-flex__fill">CPU使用率</div>
-        <div class="l-flex__fill">内存使用率</div>
-        <div class="l-flex__fill">磁盘空间使用率</div>
-        <div class="l-flex__fill col__net">网络</div>
-        <div class="l-flex__fill">状态</div>
-      </div>
-      <status-wrapper v-if="!tableData.length" />
-      <template v-else>
-        <div class="l-flex__fill u-relative">
-          <div class="c-load__list">
-            <vue-seamless-scroll
-              :data="tableData"
-              :class-option="classOption"
-            >
-              <div
-                v-for="item in tableData"
-                :key="item.id"
-                class="l-flex--row c-load__item"
-              >
-                <div class="l-flex__fill">
-                  <auto-text
-                    class="u-text--center"
-                    :text="item.ip"
-                  />
-                </div>
-                <div class="l-flex__fill item__chart l-flex--col">
-                  <LineChart
-                    class="l-flex__fill"
-                    :list="item.cpu"
-                    :color-type="0"
-                  />
-                </div>
-                <div class="l-flex__fill item__chart l-flex--col">
-                  <LineChart
-                    class="l-flex__fill"
-                    :list="item.memory"
-                    :color-type="1"
-                  />
-                </div>
-                <div class="l-flex__fill item__chart l-flex--col">
-                  <LineChart
-                    class="l-flex__fill"
-                    :list="item.disk"
-                    :color-type="2"
-                  />
-                </div>
-                <div class="l-flex__fill item__chart l-flex--col col__net">
-                  <LineChart
-                    class="l-flex__fill"
-                    :list="item.net"
-                    :color-type="3"
-                    unit="Kbps"
-                  />
-                </div>
-                <div class="l-flex__fill">
-                  <auto-text
-                    class="u-text--center"
-                    :text="item.status === 1 ? '正常' : '离线'"
-                    :style="{
-                      color: item.status === 1 ? '#04FF98' : '#F40645',
-                    }"
-                  />
-                </div>
-              </div>
-            </vue-seamless-scroll>
-          </div>
-        </div>
-      </template>
-    </div>
-  </Box>
-</template>
-
-<script>
-import Box from './Box'
-import LineChart from './LineChart'
-import VueSeamlessScroll from 'vue-seamless-scroll'
-
-export default {
-  name: 'SystemLoad',
-  components: {
-    Box,
-    VueSeamlessScroll,
-    LineChart
-  },
-  props: {
-    deviceList: {
-      type: Array,
-      default: () => []
-    }
-  },
-  data () {
-    this.$count = 0
-    return {
-      loaded: false,
-      error: false,
-      classOption: {
-        step: 0.5,
-        hoverStop: false
-      },
-      initDay: '2022-1-1',
-      tableData: []
-    }
-  },
-  computed: {
-    diffDay () {
-      return Math.floor(
-        (Date.parse(new Date()) - Date.parse(this.initDay)) / (1000 * 3600 * 24)
-      )
-    }
-  },
-  created () {
-    this.initData()
-  },
-  methods: {
-    getRandomData (value = Math.floor(50 + Math.random() * 10), limit = true) {
-      let gap = Math.floor(Math.random() * 20 - 10)
-      if (!limit) {
-        gap *= 3
-      }
-      value += gap
-      if (limit) {
-        if (value < 0) {
-          value = 10
-        }
-        if (value > 100) {
-          value = 90
-        }
-      } else if (value < 0) {
-        value = 10
-      }
-      this.$count++
-      return [this.$count, value]
-    },
-    getChartData (num, limit) {
-      const arr = [this.getRandomData(num, limit)]
-      for (let index = 0; index < 30; index++) {
-        arr.push(this.getRandomData(arr[index][1], limit))
-      }
-      return arr
-    },
-    initData () {
-      this.loaded = true
-      this.tableData = Array.from({ length: 2 }, (i, index) => {
-        return {
-          ip: ['主服务器', '副服务器'][index],
-          cpu: this.getChartData(),
-          memory: this.getChartData(),
-          disk: this.getChartData(),
-          net: this.getChartData(700, false),
-          status: 1,
-          id: index
-        }
-      })
-      this.updateValue()
-    },
-    updateValue () {
-      const map = ['cpu', 'memory', 'disk', 'net']
-      setTimeout(() => {
-        this.tableData = this.tableData.map(i => {
-          for (const key of map) {
-            i[key].shift()
-            i[key].push(
-              this.getRandomData(i[key][i[key].length - 1][1], key !== 'net')
-            )
-          }
-          return i
-        })
-        this.updateValue()
-      }, 1000)
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.c-load {
-  &__header {
-    color: #9ea9cd;
-    background-color: #313a5a;
-  }
-  .c-duration {
-    font-size: 24px;
-    color: #ffffff;
-    justify-content: center;
-    align-items: flex-end;
-    margin: 5px 0 50px;
-    &__num {
-      margin-left: 60px;
-      margin-right: 15px;
-      transform: translateY(14px);
-      font-size: 72px;
-      color: #00d1ff;
-    }
-  }
-  &__list {
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    overflow: hidden;
-  }
-
-  &__header,
-  &__item {
-    font-size: 24px;
-    line-height: 60px;
-    height: 60px;
-    text-align: center;
-  }
-  &__item {
-    color: #ffffff;
-    border-bottom: 1px solid #313a5a;
-    height: 72px;
-    line-height: 72px;
-  }
-  .item__chart {
-    height: 100%;
-  }
-  .col__net {
-    flex: 1 1 50px;
-  }
-}
-</style>

+ 0 - 641
src/views/dashboard/v2/components/CameraDetail.vue

@@ -1,641 +0,0 @@
-<template>
-  <div class="c-camera-detail">
-    <video
-      ref="video"
-      class="c-camera-detail__video o-simple-video"
-      :poster="poster"
-      autoplay
-      muted
-      @play="onVideoPlay"
-      @pause="onVideoPause"
-      @waiting="onVideoWaiting"
-      @playing="onVideoPlaying"
-      @error="onVideoError"
-      @ended="onVideoEnded"
-    />
-    <div class="c-camera-detail__footer">
-      <div class="l-flex--row c-sibling-item--v c-video-controls">
-        <div class="l-flex__auto">
-          {{ camera.model }}
-        </div>
-        <i
-          v-if="online"
-          class=" c-video-controls__btn el-icon-full-screen has-active"
-          @click="onFullScreen"
-        />
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { mapGetters } from 'vuex'
-import * as echarts from 'echarts'
-import {
-  getStatistic,
-  getVideoInfo,
-  getAvailableParams,
-  setCameraParams,
-  isOnline
-} from '@/api/camera'
-import {
-  GATEWAY_CAMERA, Camera
-} from '@/constant'
-import { parseTime } from '@/utils'
-import playerMixin from '@/components/service/external/player.js'
-
-export default {
-  name: 'CameraDetail',
-  mixins: [playerMixin],
-  props: {
-    camera: {
-      type: Object,
-      required: true
-    }
-  },
-  data () {
-    const now = new Date()
-
-    return {
-      active: 'hour', // hour是小时,day是天
-      settingActive: 'items',
-      tabs: [
-        { value: 'items', label: '分辨率' },
-        { value: 'fps', label: '帧率' },
-        { value: 'bitRates', label: '码率' }
-      ],
-      settingTab: true,
-      settingsShow: false,
-      videoSettings: null,
-      infoData: null,
-      dateValue: parseTime(now, '{y}-{m}-{d}'),
-      timeValue: parseTime(now, '{h}:00'),
-      timePickerOptions: {
-        start: '00:00',
-        step: '01:00',
-        end: '23:00'
-      }
-    }
-  },
-  computed: {
-    ...mapGetters(['token']),
-    online () {
-      return this.camera.onlineStatus === 1
-    },
-    isTraffic () {
-      return this.camera.cameraType === Camera.TRAFFIC
-    },
-    iconClass () {
-      return this.paused || this.needReset
-        ? 'el-icon-video-play'
-        : 'el-icon-video-pause'
-    }
-  },
-  created () {
-    // this.getAvailableParams()
-  },
-  mounted () {
-    this.createPlayer()
-    // if (this.isTraffic) {
-    //   this.getStatistic()
-    //   window.addEventListener('resize', this.onResize)
-    // }
-  },
-  beforeDestroy () {
-    if (this.isTraffic) {
-      this.hideSettingsMenu()
-      window.removeEventListener('resize', this.onResize)
-    }
-  },
-  methods: {
-    close () {
-      this.destroyPlayer()
-      this.$emit('close')
-    },
-    createPlayer () {
-      this.loading = true
-      isOnline(this.camera.identifier, { custom: true }).then(
-        ({ data }) => {
-          if (data) {
-            this.playUrl(
-              `${GATEWAY_CAMERA}/${this.camera.identifier}?authorization=${this.token}`
-            )
-          } else {
-            this.loading = false
-            this.$message({
-              type: 'warning',
-              message: '设备未上线,请稍后重试'
-            })
-          }
-        },
-        () => {
-          this.loading = false
-          this.$message({
-            type: 'warning',
-            message: '暂未检测到设备状态,请稍后重试'
-          })
-        }
-      )
-    },
-    setCameraParams () {
-      this.hideSettingsMenu()
-      setCameraParams({
-        deviceId: this.camera.identifier,
-        ...this.infoData
-      }).then(
-        () => {
-          this.dataInit()
-          this.onRefresh()
-        },
-        () => {
-          this.infoData = { ...this.$infoData }
-        }
-      )
-    },
-    getAvailableParams () {
-      if (this.$videoPramsLoading) {
-        this.$message({
-          type: 'warning',
-          message: '配置获取中,请稍后重试'
-        })
-        return
-      }
-      this.$videoPramsLoading = true
-      getAvailableParams()
-        .finally(() => {
-          this.$videoPramsLoading = false
-        })
-        .then(({ data }) => {
-          this.videoSettings = {
-            items: data.itemList.map(item => {
-              // maxBitRateOptions: 20480
-              // minBitRateOptions: 3
-              // resolutionFpsMax: 20
-              // snHight: 1944
-              // snWidth: 2592
-              return {
-                value: `${item.snWidth}*${item.snHight}`,
-                label: `${item.snWidth}*${item.snHight}`,
-                active: false,
-                ...item
-              }
-            }),
-            fps: [],
-            bitRates: [],
-            streamRateType: data.streamRateTypeList
-          }
-          this.getVideoInfo()
-        })
-    },
-    onSettings () {
-      if (!this.videoSettings) {
-        this.getAvailableParams()
-        return
-      }
-      if (!this.infoData) {
-        this.getVideoInfo()
-        return
-      }
-      this.settingTab = false
-      if (this.settingsShow) {
-        this.hideSettingsMenu()
-      } else {
-        document.addEventListener('click', this.hideSettingsMenu)
-        this.settingsShow = true
-      }
-    },
-    hideSettingsMenu () {
-      if (this.settingsShow) {
-        this.settingsShow = false
-        document.addEventListener('click', this.hideSettingsMenu)
-      }
-    },
-    onRefresh () {
-      this.destroyPlayer()
-      this.createPlayer()
-    },
-    onClickSettings (tab) {
-      this.settingActive = tab
-      this.settingTab = true
-    },
-    onCloseSettingTab () {
-      this.settingTab = false
-    },
-    getVideoInfo () {
-      console.log('getVideoInfo', this.$videoInfoLoading)
-      if (this.$videoInfoLoading) {
-        this.$message({
-          type: 'warning',
-          message: '配置获取中,请稍后重试'
-        })
-        return
-      }
-      this.$videoInfoLoading = true
-      getVideoInfo(this.camera.identifier)
-        .finally(() => {
-          this.$videoInfoLoading = false
-        })
-        .then(({ data }) => {
-          if (data) {
-            const { width, hight, frameRate, bitRate } = data
-            this.infoData = { width, hight, frameRate, bitRate }
-            this.dataInit()
-          } else {
-            this.$message({
-              type: 'warning',
-              message: '未获取到摄像头配置,请联系管理员'
-            })
-          }
-        })
-    },
-    dataInit () {
-      const { width, hight, frameRate, bitRate } = this.infoData
-      const value = `${width}*${hight}`
-      let target = null
-
-      this.videoSettings.items.forEach(item => {
-        if (item.value === value) {
-          item.active = true
-          target = item
-        } else {
-          item.active = false
-        }
-      })
-
-      if (target) {
-        const fps = []
-        const max = target.resolutionFpsMax
-        for (let i = 1; i <= max; i++) {
-          fps.push({ value: i, label: `${i}fps`, active: i === frameRate })
-        }
-        this.videoSettings.fps = fps
-
-        const bitRates = []
-        const minBitRate = target.minBitRateOptions
-        const maxBitRate = target.maxBitRateOptions
-        const streamRateType = this.videoSettings.streamRateType
-        for (let i = 0; i < streamRateType.length; i++) {
-          const rateType = streamRateType[i]
-          if (rateType >= minBitRate && rateType <= maxBitRate) {
-            bitRates.push({
-              value: rateType,
-              label: `${rateType}kb/s`,
-              active: rateType === bitRate
-            })
-          }
-        }
-        this.videoSettings.bitRates = bitRates
-      } else {
-        this.videoSettings.items = [
-          { label: `${width}*${hight}`, active: true }
-        ]
-        this.videoSettings.fps = [
-          { value: frameRate, label: `${frameRate}fps`, active: true }
-        ]
-        this.videoSettings.bitRates = [
-          { value: bitRate, label: `${bitRate}kb/s`, active: true }
-        ]
-      }
-    },
-    settingClick (item) {
-      let value = null
-      switch (this.settingActive.value) {
-        case 'items':
-          value = `${this.infoData.width}*${this.infoData.hight}`
-          break
-        case 'fps':
-          value = this.infoData.frameRate
-          break
-        case 'bitRates':
-          value = this.infoData.bitRate
-          break
-        default:
-          return
-      }
-      if (value === item.value) {
-        return
-      }
-      this.$infoData = { ...this.infoData }
-      switch (this.settingActive.value) {
-        case 'items':
-          this.infoData.width = item.snWidth
-          this.infoData.hight = item.snHight
-          this.infoData.frameRate = Math.min(
-            item.resolutionFpsMax,
-            this.infoData.frameRate
-          )
-          this.infoData.bitRate = Math.max(
-            item.minBitRateOptions,
-            Math.min(item.maxBitRateOptions, this.infoData.bitRate)
-          )
-          break
-        case 'fps':
-          this.infoData.frameRate = item.value
-          break
-        case 'bitRates':
-          this.infoData.bitRate = item.value
-          break
-        default:
-          break
-      }
-      this.setCameraParams()
-    },
-    onTimeTypeChanged (type) {
-      if (this.active === type) {
-        return
-      }
-      this.active = type
-      this.getStatistic()
-    },
-    getStatistic () {
-      const endTime = `${this.dateValue} ${this.timeValue}:00`
-      const date = new Date(endTime)
-      switch (this.active) {
-        case 'hour':
-          date.setHours(date.getHours() - 1)
-          break
-        default:
-          date.setDate(date.getDate() - 1)
-          break
-      }
-      const startTime = parseTime(date, '{y}-{m}-{d} {h}:{i}:{s}')
-      this.refreshEchart([])
-      getStatistic({
-        deviceId: this.camera.identifier,
-        startTime,
-        endTime,
-        pageIndex: 1,
-        pageSize: 10000
-      }).then(({ data }) => {
-        this.refreshEchart(data)
-      })
-    },
-    getEchartData (data) {
-      const date = new Date(`${this.dateValue} ${this.timeValue}:00`)
-      const xdata = []
-      const ydata = []
-      if (this.active === 'hour') {
-        date.setHours(date.getHours() - 1)
-        for (let i = 0; i <= 60; i++) {
-          const value = parseTime(date, '{y}-{m}-{d} {h}:{i}')
-          xdata.push(value.split(' ')[1])
-          ydata.push(data[value] || 0)
-          date.setMinutes(date.getMinutes() + 1)
-        }
-      } else {
-        date.setDate(date.getDate() - 1)
-        for (let i = 0; i <= 24; i++) {
-          const value = parseTime(date, '{y}-{m}-{d} {h}')
-          xdata.push(`${value.split(' ')[1]}:00`)
-          ydata.push(data[value] || 0)
-          date.setHours(date.getHours() + 1)
-        }
-      }
-      return { xdata, ydata }
-    },
-    transformEchartData (data) {
-      const ydata = {}
-      const isHour = this.active === 'hour'
-      data.forEach(({ eventTime, insidePeopleNum }) => {
-        const key = eventTime.slice(0, isHour ? 16 : 13)
-        if (ydata[key]) {
-          ydata[key] = Math.max(ydata[key], insidePeopleNum)
-        } else {
-          ydata[key] = insidePeopleNum
-        }
-      })
-      return this.getEchartData(ydata)
-    },
-    onResize () {
-      this.$echarts?.resize()
-    },
-    refreshEchart (echartsData) {
-      const { xdata, ydata } = this.transformEchartData(echartsData)
-      if (!this.$echarts) {
-        this.$echarts = echarts.init(document.getElementById('main'))
-      }
-      this.$echarts?.setOption({
-        title: {
-          text: '区域内人数',
-          textStyle: {
-            color: '#fff',
-            fontWeight: 'bold'
-          }
-        },
-        xAxis: {
-          type: 'category',
-          data: xdata,
-          axisLine: {
-            lineStyle: {
-              color: '#4779BC'
-            }
-          },
-          axisLabel: {
-            color: '#A9CEFF'
-          }
-        },
-        yAxis: {
-          type: 'value',
-          minInterval: 1,
-          splitLine: {
-            lineStyle: {
-              color: '#4779BC',
-              type: 'dashed'
-            }
-          },
-          axisLine: {
-            lineStyle: {
-              color: '#4779BC'
-            }
-          },
-          axisLabel: {
-            color: '#A9CEFF'
-          }
-        },
-        grid: {
-          left: '30',
-          right: '20',
-          top: '40',
-          bottom: '20'
-        },
-        series: [
-          {
-            data: ydata,
-            type: 'bar',
-            showBackground: true,
-            backgroundStyle: {
-              color: 'transparent'
-            },
-            itemStyle: {
-              color: 'rgba(0, 191, 208, 0.5)'
-            },
-            select: {
-              itemStyle: {
-                color: 'rgb(0, 234, 255)'
-              }
-            }
-          }
-        ],
-        tooltip: {
-          formatter: '时间:{b}<br />人流量:{c}'
-        }
-      })
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-$theme-blue: #003e90;
-
-.c-camera-detail {
-  position: relative;
-  width: 100%;
-  height: 100%;
-  background-color: #000;
-  overflow: hidden;
-
-  &__video {
-    width: 100%;
-    height: 100%;
-  }
-
-  &__header {
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: $height;
-    background-color: rgba($theme-blue, 0.8);
-    z-index: 9;
-
-    &::after {
-      content: "";
-      position: absolute;
-      top: 100%;
-      left: 50%;
-      width: 700px;
-      height: 0;
-      border-top: $padding--lg solid rgba($theme-blue, 0.8);
-      border-right: $padding--lg solid transparent;
-      border-bottom: $padding--lg solid transparent;
-      border-left: $padding--lg solid transparent;
-      transform: translateX(-50%);
-    }
-  }
-
-  &__footer {
-    position: absolute;
-    left: 0;
-    bottom: 0;
-    width: 100%;
-  }
-
-  &__traffic {
-    position: relative;
-    line-height: 1;
-    border-radius: $radius--sm;
-    background-color: rgba($theme-blue, 0.8);
-  }
-}
-
-.c-video-controls {
-  position: relative;
-  padding: $padding $padding--lg;
-  border-radius: $radius--sm;
-  background-color: rgba(#00060d, 0.75);
-
-  &__btn {
-    color: #fff;
-    font-size: $font-size--3xl;
-  }
-}
-
-.settingB {
-  position: absolute;
-  right: 134px;
-  bottom: 48px;
-  padding: 10px 0px;
-  color: #fff;
-  background-color: rgba(#000, 0.85);
-  transform: translateX(50%);
-
-  .settingT {
-    position: relative;
-    padding: 0px 16px;
-    width: 180px;
-    height: 40px;
-    line-height: 40px;
-    cursor: pointer;
-
-    &:hover {
-      background-color: rgba(#454545, 0.85);
-    }
-
-    i {
-      position: absolute;
-      top: 13px;
-      right: 16px;
-    }
-  }
-
-  .settingHeight {
-    max-height: 250px;
-    overflow: auto;
-  }
-
-  .settingsub {
-    width: 140px;
-    padding-left: 42px;
-
-    i {
-      position: absolute;
-      left: 16px;
-    }
-  }
-}
-
-.c-choose-date {
-  position: absolute;
-  right: $spacing;
-  top: $spacing;
-  color: #fff;
-
-  &__type {
-    display: inline-block;
-    height: 24px;
-    line-height: 24px;
-    border-radius: $radius--sm;
-    background-color: #4478bc;
-  }
-
-  &__item {
-    display: inline-block;
-    width: 50px;
-    border-radius: $radius--sm;
-    background-color: #4478bc;
-
-    &.active {
-      background-color: #0096ff;
-    }
-  }
-
-  ::v-deep input {
-    height: 24px;
-    padding-right: $padding;
-    color: #fff;
-    font-size: $font-size--sm;
-    line-height: 24px;
-    background-color: transparent;
-  }
-
-  ::v-deep .el-input__icon {
-    line-height: 24px;
-  }
-}
-
-.o-canvas {
-  width: 100%;
-  height: 200px;
-}
-</style>

+ 0 - 346
src/views/dashboard/v2/components/DevicePlayer.vue

@@ -1,346 +0,0 @@
-<template>
-  <div
-    class="o-video"
-    :class="{
-      offline: !online,
-      mask: !isPlaying,
-      controls,
-      floating,
-      fullscreen: isFullscreen,
-    }"
-    @mousemove="onMouseMove"
-  >
-    <template v-if="online">
-      <video
-        ref="video"
-        class="o-video__player o-simple-video"
-        :poster="poster"
-        autoplay
-        muted
-        @play="onVideoPlay"
-        @pause="onVideoPause"
-        @waiting="onVideoWaiting"
-        @playing="onVideoPlaying"
-        @error="onVideoError"
-        @ended="onVideoEnded"
-      />
-      <div class="o-video__mask">
-        <div
-          class="l-flex--row center o-video__btn u-pointer"
-          @click.stop="onPlayOrPause"
-        >
-          <i :class="statusIconClass" />
-        </div>
-      </div>
-    </template>
-    <div
-      v-if="controls"
-      class="l-flex--row c-header"
-    >
-      <slot name="header" />
-    </div>
-    <div
-      v-if="controls"
-      class="l-flex--row c-footer"
-    >
-      <div class="l-flex__fill c-sibling-item u-ellipsis">
-        {{ device.name }}
-      </div>
-      <slot
-        name="controls"
-        :can-play="canPlay"
-        :on-full-screen="onFullScreen"
-        :waiting-or-loading="loading||waiting"
-        :online="online"
-        :is-playing="isPlaying"
-      >
-        <template v-if="canPlay">
-          <i
-            v-if="loadingQuality"
-            class="c-sibling-item el-icon-loading"
-          />
-          <div
-            v-else
-            class="l-flex__none c-sibling-item o-quality-menu u-pointer"
-            @click.stop="toggleQualityMenu"
-          >
-            <div
-              v-if="showQualityMenu"
-              class="o-quality-menu__list u-font-size--sm u-text--center"
-            >
-              <div
-                v-for="item in qualities"
-                :key="item.value"
-                class="o-quality-menu__item has-active"
-                :class="{ 'u-color--success': quality.value === item.value }"
-                @click="changeQuality(item)"
-              >
-                {{ item.label }}
-              </div>
-            </div>
-            <span class="has-active">{{ quality.label }}</span>
-          </div>
-          <i
-            class="c-sibling-item el-icon-full-screen has-active"
-            @click="onFullScreen"
-          />
-        </template>
-      </slot>
-    </div>
-  </div>
-</template>
-
-<script>
-import {
-  authCode,
-  getRecordConfig,
-  addRecordConfig,
-  updateRecordConfig
-} from '@/api/device'
-import { GATEWAY } from '@/constant'
-import playerMixin from '@/components/service/external/player.js'
-
-const Quality = {
-  fff: {
-    videoWidth: 640,
-    videoHeight: 360,
-    videoBitRate: 36 * 1024,
-    frameRate: 1
-  },
-  ff: {
-    videoWidth: 1280,
-    videoHeight: 720,
-    videoBitRate: 100 * 1024,
-    frameRate: 10
-  },
-  f: {
-    videoWidth: 1920,
-    videoHeight: 1080,
-    videoBitRate: 1024 * 1024,
-    frameRate: 20
-  }
-}
-
-export default {
-  name: 'DevicePlayer',
-  mixins: [playerMixin],
-  props: {
-    device: {
-      type: Object,
-      required: true
-    }
-  },
-  data () {
-    return {
-      qualities: [
-        { value: 'fff', label: '标清' },
-        { value: 'ff', label: '高清' },
-        { value: 'f', label: '超清' }
-      ],
-      loadingQuality: false,
-      showQualityMenu: false,
-      quality: null,
-      recordConfig: null,
-      floating: true
-    }
-  },
-  computed: {
-    online () {
-      return this.device.onlineStatus === 1
-    },
-    canPlay () {
-      return !this.loading && !this.needReset
-    }
-  },
-  watch: {
-    online (val) {
-      if (val) {
-        this.$nextTick(this.createPlayer)
-      } else {
-        this.hideQualityMenu()
-        this.onVideoReset()
-        this.destroyPlayer()
-      }
-    },
-    isFullscreen () {
-      this.onMouseMove()
-    }
-  },
-  created () {
-    this.$delayMoveTimer = -1
-    this.$timer = -1
-    if (this.online) {
-      this.createPlayer()
-    }
-  },
-  beforeDestroy () {
-    clearTimeout(this.$delayMoveTimer)
-    this.hideQualityMenu()
-  },
-  methods: {
-    onMouseMove () {
-      clearTimeout(this.$delayMoveTimer)
-      this.floating = false
-      if (this.isFullscreen) {
-        this.$delayMoveTimer = setTimeout(() => {
-          this.floating = true
-        }, 3000)
-      }
-    },
-    onVideoReset () {
-      this.recordConfig = null
-      this.$playerInfo = null
-    },
-    getRecordConfig () {
-      this.loadingQuality = true
-      getRecordConfig(this.device.id, { custom: true })
-        .finally(() => {
-          this.loadingQuality = false
-        })
-        .then(
-          ({ data }) => {
-            if (data) {
-              const { frameRate } = data
-              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()
-            } else {
-              this.setRecordConfig(this.qualities[0])
-            }
-          },
-          () => {
-            this.onVideoDestroyByError()
-          }
-        )
-    },
-    setRecordConfig (quality) {
-      this.loadingQuality = true;
-      (this.recordConfig ? updateRecordConfig : addRecordConfig)(
-        {
-          deviceId: this.device.id,
-          ...Quality[quality.value]
-        },
-        { custom: true }
-      )
-        .then(
-          ({ data }) => {
-            this.quality = quality
-            this.recordConfig = data
-            this.createPlayer()
-          },
-          () => {
-            this.onVideoDestroyByError()
-          }
-        )
-        .finally(() => {
-          this.loadingQuality = false
-        })
-    },
-    hideQualityMenu () {
-      if (this.showQualityMenu) {
-        this.showQualityMenu = false
-        document.removeEventListener('click', this.hideQualityMenu)
-      }
-    },
-    toggleQualityMenu () {
-      if (this.showQualityMenu) {
-        this.hideQualityMenu()
-      } else {
-        document.addEventListener('click', this.hideQualityMenu)
-        this.showQualityMenu = true
-      }
-    },
-    changeQuality (quality) {
-      if (this.quality.value !== quality.value) {
-        this.$playerInfo = null
-        this.setRecordConfig(quality)
-      } else if (this.needReset) {
-        this.createPlayer()
-      }
-    },
-    getAuthCode () {
-      this.$playerInfo = null
-      authCode(this.recordConfig.stream).then(
-        ({ data }) => {
-          if (this.$timer !== null) {
-            this.$playerInfo = data
-            this.createPlayer()
-          }
-        },
-        () => {
-          this.onVideoDestroyByError()
-        }
-      )
-    },
-    createPlayer () {
-      if (this.$timer === null) {
-        return
-      }
-      this.loading = true
-      clearTimeout(this.$timer)
-      if (!this.recordConfig) {
-        this.getRecordConfig()
-        return
-      }
-      if (!this.$playerInfo) {
-        this.getAuthCode()
-        return
-      }
-      const {
-        vhost = '__defaultVhost__',
-        token,
-        timestamp,
-        expire
-      } = this.$playerInfo
-      if (Number(timestamp) + Number(expire) * 1000 <= Date.now()) {
-        this.getAuthCode()
-        return
-      }
-      this.destroyPlayer()
-      this.playUrl(
-        `${GATEWAY}/live/${this.recordConfig.stream}.flv?vhost=${vhost}&authorization=${token}&timestamp=${timestamp}&expire=${expire}`
-      )
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.o-quality-menu {
-  display: inline-block;
-  position: relative;
-  padding: 0 $padding--xs;
-  z-index: 1;
-
-  &__list {
-    position: absolute;
-    right: 0;
-    bottom: 100%;
-    width: 100%;
-    margin-bottom: $spacing--2xs;
-    border-radius: $radius;
-    background-color: rgba(#000, 0.85);
-    z-index: -1;
-  }
-
-  &__item {
-    padding: $padding--2xs 0;
-  }
-}
-.c-header {
-  position: absolute;
-  left: 0;
-  top: 0;
-  width: 100%;
-  padding: 10px  16px;
-  color: #fff;
-  line-height: 1;
-  background-image: trans;
-}
-</style>

+ 0 - 4
src/views/dashboard/v2/index.vue

@@ -211,10 +211,6 @@ export default {
     background: url("~@/assets/v1/monitor_bg.png");
     transform-origin: left top;
   }
-  &__bg {
-    background: url("~@/assets/v2/map.png");
-    background-position: center;
-  }
 }
 .dashboard-block {
   & ~ & {