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

refactor: video streaming viewing interaction

Casper Dai пре 2 година
родитељ
комит
39a6543d17
2 измењених фајлова са 133 додато и 31 уклоњено
  1. 1 1
      src/components/service/external/DevicePlayer/index.vue
  2. 132 30
      src/views/device/record/index.vue

+ 1 - 1
src/components/service/external/DevicePlayer/index.vue

@@ -30,7 +30,7 @@
     </template>
     <div
       v-if="controls"
-      class="l-flex--row c-footer"
+      class="l-flex--row c-footer u-font-size--sm"
     >
       <div class="l-flex__fill c-sibling-item u-ellipsis">{{ device.name }}</div>
       <slot

+ 132 - 30
src/views/device/record/index.vue

@@ -4,49 +4,151 @@
     margin
     padding
     background
+    horizontal
   >
-    <grid-table
-      ref="table"
-      size="large"
-      :schema="schema"
-    >
-      <grid-table-item v-slot="item">
-        <device-player
-          :key="item.id"
-          :device="item"
-          controls
-          autoplay
-          retry
-          keep
-          check-online
-          use-initial
+    <device-tree
+      class="c-sibling-item c-sidebar u-width--lg"
+      shrink
+      checkbox
+      check-on-click-node
+      :default-checked-nodes="devices"
+      @loaded="onDeviceLoaded"
+      @change="onChange"
+    />
+    <div class="l-flex--col l-flex__fill c-sibling-item far">
+      <div class="l-flex__none l-flex--row c-sibling-item--v">
+        <div class="l-flex__none c-sibling-item u-font-size--sm u-bold">视频墙列数</div>
+        <el-select
+          v-model="colCount"
+          class="c-sibling-item u-width--xs"
+          size="mini"
+        >
+          <el-option
+            v-for="option in colOptions"
+            :key="option.value"
+            :label="option.label"
+            :value="option.value"
+          />
+        </el-select>
+      </div>
+      <template v-if="hasData">
+        <div class="l-flex__fill c-sibling-item--v u-overflow--auto">
+          <draggable
+            class="c-record-grid"
+            :style="gridStyle"
+            handle=".o-video"
+            animation="300"
+          >
+            <device-player
+              v-for="item in devices"
+              :key="item.id"
+              :device="item"
+              controls
+              autoplay
+              retry
+              keep
+              check-online
+            />
+          </draggable>
+        </div>
+      </template>
+      <template v-else>
+        <el-empty
+          class="l-flex__fill l-flex--row center"
+          description="请选择设备"
         />
-      </grid-table-item>
-    </grid-table>
+      </template>
+    </div>
   </wrapper>
 </template>
 
 <script>
-import { getDevices } from '@/api/device'
+import Draggable from 'vuedraggable'
 
 export default {
   name: 'DeviceRecord',
+  components: {
+    Draggable
+  },
   data () {
     return {
-      schema: {
-        pageSize: 9,
-        list: getDevices,
-        condition: { activate: 1, onlineStatus: 1 },
-        filters: [
-          { key: 'onlineStatus', type: 'select', options: [
-            { value: void 0, label: '所有' },
-            { value: 1, label: '在线' }
-          ] },
-          { key: 'name', placeholder: '设备名称', type: 'search' },
-          { type: 'refresh' }
-        ]
+      colOptions: [
+        { value: 2, label: '2列' },
+        { value: 3, label: '3列' },
+        { value: 4, label: '4列' },
+        { value: 5, label: '5列' },
+        { value: -1, label: '自适应' }
+      ],
+      colCount: 3,
+      devices: []
+    }
+  },
+  computed: {
+    hasData () {
+      return this.devices.length > 0
+    },
+    gridStyle () {
+      switch (this.colCount) {
+        case -1:
+          return {
+            'grid-template-columns': 'repeat(auto-fill, 320px)'
+          }
+        case 2:
+          return {
+            'grid-template-columns': `repeat(${this.colCount}, 400px)`
+          }
+        case 3:
+          return {
+            'grid-template-columns': `repeat(${this.colCount}, 320px)`
+          }
+        default:
+          return {
+            'grid-template-columns': `repeat(${this.colCount}, 1fr)`
+          }
       }
     }
+  },
+  methods: {
+    onDeviceLoaded (data) {
+      const count = this.colCount > 0 ? this.colCount * this.colCount : 9
+      if (count) {
+        this.devices = this.addDefaultDevices(data, count, [])
+      }
+    },
+    addDefaultDevices ({ children, devices }, count, arr) {
+      if (arr.length < count && devices?.length) {
+        for (let i = 0; i < devices.length; i++) {
+          if (devices[i].onlineStatus === 1) {
+            arr.push(this.transformDevice(devices[i]))
+            if (arr.length >= count) {
+              return arr
+            }
+          }
+        }
+      }
+      if (arr.length < count && children?.length) {
+        for (let i = 0; i < children.length; i++) {
+          this.addDefaultDevices(children[i], count, arr)
+          if (arr.length >= count) {
+            return arr
+          }
+        }
+      }
+      return arr
+    },
+    transformDevice ({ id, productId, name }) {
+      return { id, productId, name }
+    },
+    onChange (devices) {
+      this.devices = devices
+    }
   }
 }
 </script>
+
+<style lang="scss" scoped>
+.c-record-grid {
+  display: grid;
+  gap: $spacing--3xs;
+}
+</style>