瀏覽代碼

fix: 新建CameraTreeOldVersion,适配Playback组件使用

bxy 1 年之前
父節點
當前提交
d48a2587ea

+ 213 - 0
src/views/cameras/preview/components/CameraTree/CameraTreeOldVersion.vue

@@ -0,0 +1,213 @@
+<template>
+  <div class="cameraTreeWrapper">
+    <div class="cameraTreeTitle">
+      <span>场景树</span>
+      <span class="detail-num" v-if="props.total"
+        >(总相机:{{ props.total }} 未联网:{{ props.noNetworkingNum }} 未进入平台:{{
+          props.noIntegrationNum
+        }})</span
+      ></div
+    >
+    <div class="cameraTreeInputWrapper">
+      <el-input
+        v-model="filterText"
+        placeholder="请输入相机的名称进行搜索"
+        :suffix-icon="Search"
+        class="filterTextInput"
+      />
+      <el-scrollbar class="tree-scroll">
+        <el-tree
+          :data="props.cameraTree"
+          :props="defaultProps"
+          @node-click="handleNodeClick"
+          node-key="code"
+          :default-expand-all="true"
+          :filter-node-method="filterNode"
+          ref="treeRef"
+          v-loading="props.loading"
+        >
+          <template #default="{ node, data }">
+            <span class="flexCenter" :class="{ integrationState: data.integrationState === 1 }">
+              <span
+                v-if="data.nodeType === CameraTreeNodeType.camera"
+                class="iconWrapper flexCenter"
+              >
+                <span
+                  class="cameraCommon"
+                  :class="{
+                    cameraSelect: isSelect(data),
+                  }"
+                ></span>
+
+                <el-icon
+                  class="cameraIcon"
+                  :class="{
+                    iconSelect: isSelect(data),
+                  }"
+                >
+                  <VideoCamera />
+                </el-icon>
+                <el-icon class="invalidCamera" v-if="isInvalid(data)"><WarningFilled /></el-icon>
+              </span>
+              {{ node.label }}
+            </span>
+          </template>
+        </el-tree>
+      </el-scrollbar>
+    </div>
+  </div>
+</template>
+<script lang="ts" setup>
+  import { ElMessage, ElTree } from 'element-plus';
+  import { ref, watch } from 'vue';
+  import { useRouteQuery } from '@vueuse/router';
+  import { Search, VideoCamera, WarningFilled } from '@element-plus/icons-vue';
+
+  import useCameraDetail from '../../store/useCameraDetailStore';
+  import { CameraTree, CameraTreeNodeType } from '@/api/camera/camera-preview';
+
+  const props = defineProps<{
+    cameraTree: Tree[];
+    loading: boolean;
+    total: number;
+    noNetworkingNum?: number;
+    noIntegrationNum?: number;
+  }>();
+
+  interface Tree {
+    [key: string]: any;
+  }
+
+  const { setDetail } = useCameraDetail();
+
+  const cameraId = useRouteQuery('cameraId');
+  const defaultProps = {
+    children: 'children',
+    label: 'name',
+  };
+
+  const handleNodeClick = (e: CameraTree) => {
+    console.log('e', e);
+    if (e.integrationState === 1) {
+      ElMessage.error('该相机未进入平台');
+    } else {
+      if (e.nodeType === CameraTreeNodeType.camera) {
+        cameraId.value = String(e.id);
+        setDetail(e);
+      }
+    }
+  };
+
+  const isSelect = (data) =>
+    data.nodeType === CameraTreeNodeType.camera && data.id === Number(cameraId.value);
+
+  const filterText = ref('');
+  const treeRef = ref<InstanceType<typeof ElTree>>();
+
+  watch(filterText, (val) => {
+    childrenNodeList.value = [];
+    treeRef.value!.filter(val);
+  });
+
+  const childrenNodeList = ref<string[]>([]);
+
+  function extractCodes(data: any[], codes: string[] = []) {
+    data.forEach((item) => {
+      codes.push(item.data.code);
+      if (item.childNodes) {
+        extractCodes(item.childNodes, codes);
+      }
+    });
+    return codes;
+  }
+
+  const filterNode = (value: string, data: Tree, node) => {
+    if (!value) return true;
+    // 检查当前节点的 label 是否包含关键词
+    const labelMatch = data.name.includes(value);
+
+    if (labelMatch) {
+      if (node.childNodes && node.childNodes.length > 0) {
+        childrenNodeList.value = extractCodes(node.childNodes, []);
+      }
+    }
+
+    if (childrenNodeList.value.includes(data.code)) {
+      return true;
+    } else {
+      return labelMatch;
+    }
+  };
+
+  const isInvalid = (data) => {
+    return data.networkingState !== 0;
+  };
+</script>
+<style scoped>
+  .cameraCommon {
+    width: 6px;
+    height: 6px;
+    display: inline-block;
+    align-items: center;
+    margin-right: 6px;
+  }
+
+  .tree-scroll {
+    height: calc(100vh - 64px - 170px);
+  }
+
+  .cameraSelect {
+    width: 6px;
+    height: 6px;
+    background: #0052d9;
+    display: inline-block;
+    border-radius: 6px;
+    margin-right: 6px;
+  }
+  .cameraTreeTitle {
+    background: #f0f2f5;
+    padding: 12px;
+    display: flex;
+  }
+
+  .detail-num {
+    font-size: 10px;
+    margin-top: 4px;
+    margin-left: 6px;
+  }
+
+  .cameraTreeInputWrapper {
+    padding: 8px;
+  }
+  .filterTextInput {
+    margin: 8px 0;
+  }
+  .flexCenter {
+    display: flex;
+    align-items: center;
+  }
+
+  .integrationState {
+    cursor: not-allowed;
+    color: #ccc;
+  }
+  .cameraIcon {
+    margin-right: 5px;
+    font-size: 18px;
+  }
+  .iconSelect {
+    color: #0052d9;
+  }
+
+  .iconWrapper {
+    position: relative;
+  }
+
+  .invalidCamera {
+    color: #dd5869;
+    font-size: 12px;
+    position: absolute;
+    right: 2px;
+    top: -4px;
+  }
+</style>

+ 1 - 1
src/views/datamanager/playback/Playback.vue

@@ -20,7 +20,7 @@
 
 <script setup lang="ts">
   import NvrCameraView from './components/NvrCameraView.vue';
-  import CameraTreeCom from '@/views/cameras/preview/components/CameraTree/CameraTree.vue';
+  import CameraTreeCom from '@/views/cameras/preview/components/CameraTree/CameraTreeOldVersion.vue';
   import { onUnmounted, onBeforeUnmount, ref, watch } from 'vue';
   import useCameraDetail from '@/views/cameras/preview/store/useCameraDetailStore';
   import usePresetListStore from '@/views/cameras/preview/store/usePresetListStore';