Hwf пре 8 месеци
родитељ
комит
d21545ccf9

+ 0 - 22
src/api/routineCommandMap/index.ts

@@ -1,26 +1,4 @@
 import request from '@/utils/request';
-import { EmergencyVideoParams } from '@/api/routineCommandMap/type';
-
-// 获取视频监控列表
-export function getEmergencyVideoCata(data: EmergencyVideoParams) {
-  return request({
-    url: '/api/gateway/v2/emergency_video_cata',
-    method: 'post',
-    data: data
-  });
-}
-
-// 获取视频地址
-export function getVideoUrlById(id: string) {
-  return request({
-    url: '/api/videoResource/hkvideo/get_video_url_by_id',
-    method: 'get',
-    params: {
-      id: id,
-      protocol: 'wss'
-    }
-  });
-}
 
 // 获取预案管理列表
 export function getEmergencyPlanList(params) {

+ 48 - 0
src/api/videoMonitor/index.ts

@@ -0,0 +1,48 @@
+import request from '@/utils/request';
+
+// 获取视频监控列表
+export function getEmergencyVideoCata(data) {
+  return request({
+    url: '/api/gateway/v2/emergency_video_cata',
+    method: 'post',
+    data: data
+  });
+}
+
+// 获取视频地址
+export function getVideoUrlById(id: string) {
+  return request({
+    url: '/api/videoResource/hkvideo/get_video_url_by_id',
+    method: 'get',
+    params: {
+      id: id,
+      protocol: 'wss'
+    }
+  });
+}
+
+// 视频点位查询接口-用户专属
+export function getVideoListByUser(params) {
+  return request({
+    url: '/api/videoResource/videoinfo/get_video_list_by_user',
+    method: 'get',
+    params
+  });
+}
+
+// 获取用户绑定视频点位
+export function getUserVideoPoints() {
+  return request({
+    url: '/system/user/videoPoints',
+    method: 'get'
+  });
+}
+
+// 更新用户绑定视频点位
+export function updateUserVideoPoints(data) {
+  return request({
+    url: '/system/user/videoPoints',
+    method: 'put',
+    data: data
+  });
+}

+ 1 - 1
src/components/HKVideo/index.vue

@@ -25,7 +25,7 @@
 
 <script setup lang="ts" name="HKVideo">
 import HikvisionPlayer from './hikvision-h5player.vue';
-import { getVideoUrlById } from '@/api/routineCommandMap';
+import { getVideoUrlById } from '@/api/videoMonitor';
 
 const props = defineProps({
   dot_data: Object,

+ 2 - 2
src/components/Map/index.vue

@@ -162,10 +162,10 @@ const handlePointDetails = (data) => {
   let method = methodList[data.dataType];
   if (!method) return;
   method(data.id).then((res) => {
-    if(!!pointDetailTemplate[data.dataType]) {
+    if (!!pointDetailTemplate[data.dataType]) {
       let content = document.createElement('div');
       content.className = 'point-info';
-      for(let key in res.rows[0]) {
+      for (let key in res.rows[0]) {
         let keyLabel = !!pointDetailTemplate[data.dataType][key] ? pointDetailTemplate[data.dataType][key] : key
         const div = document.createElement('div');
         div.className = 'point-item';

+ 81 - 20
src/views/emergencyCommandMap/LeftSection/VideoMonitor.vue

@@ -15,7 +15,7 @@
       </div>
     </div>
   </div>
-  <Dialog v-model="showListDialog" title="视频监控" @closeDialog="reset">
+  <Dialog v-model="showListDialog" title="视频监控" width="3441px" height="2000px" @closeDialog="reset">
     <div class="search-box">
       <div v-show="!editVideo" class="box-left" @click="activeEdit">
         <el-button type="primary" size="large">编辑首页视频</el-button>
@@ -24,9 +24,10 @@
         <el-button type="primary" size="large" @click="handleSave">保存</el-button>
         <el-button type="danger" size="large" @click="handleCancel">取消编辑</el-button>
         <div class="flex">
-          <div class="box-item">
-            <div class="img2">
-
+          <div v-for="(item, index) in editData" :key="index" class="box-item">
+            <div class="edit-img">
+              <span class="edit-title">{{ item.name }}</span>
+              <div class="close-btn" @click="deleteItem(index)">x</div>
             </div>
           </div>
         </div>
@@ -50,12 +51,12 @@
       </div>
     </div>
     <div class="video-list2">
-      <div v-for="(item, index) in dialogListData" :key="index" class="video-box">
+      <div v-for="(item, index) in dialogListData" :key="index" class="video-box" @click="selectItem(item)">
         <div class="video-label">
           <span class="label">{{ item.name }}</span>
         </div>
         <div style="width: 733px; height: 300px; display: flex; align-items: center; justify-content: center">
-          <div v-if="editVideo" class="edit-box">
+          <div v-if="editVideo">
             <div v-if="item.sort" class="active-tag">首页展示</div>
             <div class="img"></div>
           </div>
@@ -75,16 +76,22 @@
 </template>
 
 <script lang="ts" setup name="VideoMonitor">
-import { getEmergencyVideoCata } from '@/api/routineCommandMap';
+import {
+  getEmergencyVideoCata,
+  getUserVideoPoints,
+  getVideoListByUser,
+  updateUserVideoPoints
+} from '@/api/videoMonitor';
+import { deepClone } from '@/utils';
 
 const proxy = getCurrentInstance()?.proxy;
 const { realistic_video } = toRefs<any>(proxy?.useDict('realistic_video'));
 
 let listData = ref([]);
 const initData = () => {
-  getEmergencyVideoCata({
-    current: 1,
-    size: 6
+  getVideoListByUser({
+    page: 1,
+    pageSize: 6
   }).then((res) => {
     listData.value = res.rows;
   });
@@ -102,6 +109,8 @@ const queryParams = reactive({
 let showListDialog = ref(false);
 let total = ref(0);
 let editVideo = ref(false);
+// 选中的视频
+let selectData = ref([]);
 let editData = ref([]);
 let dialogListData = ref([]);
 const showVideoMonitorList = () => {
@@ -109,20 +118,35 @@ const showVideoMonitorList = () => {
   showListDialog.value = true;
 };
 
-const getList = () => {
+const getList = async () => {
+  await getUserVideoPoints().then((res) => {
+    selectData.value = res.data.videoInfos;
+  });
   getEmergencyVideoCata(queryParams).then((res) => {
-    for (let i = 0; i < 6; i++) {
-      if (res.rows && res.rows[i]) {
-        res.rows[i].sort = i.toString();
-        editData.value.push(res.rows[i]);
-      } else {
-        break;
+    selectData.value.forEach((item) => {
+      for (let i = 0; i < res.rows.length; i++) {
+        if (item.video_code_int === res.rows[i].video_code) {
+          res.rows[i].sort = true;
+          break;
+        }
       }
-    };
+    });
     dialogListData.value = res.rows;
     total.value = res.total;
   });
 };
+const selectItem = (item) => {
+  if (editVideo.value) {
+    if (editData.value.length >= 6) {
+      ElMessage.error('首页视频数量已达6个上限,如需继续操作请先取消已选择视频。');
+    } else {
+      editData.value.push(item);
+    }
+  }
+};
+const deleteItem = (index) => {
+  editData.value.splice(index, 1);
+};
 /** 表单重置 */
 const reset = () => {
   queryParams.current = 1;
@@ -144,6 +168,7 @@ const resetQuery = () => {
 
 // 开启编辑视频
 const activeEdit = () => {
+  editData.value = deepClone(selectData.value)
   editVideo.value = true;
 };
 // 关闭编辑
@@ -152,7 +177,14 @@ const handleCancel = () => {
 };
 // 保存编辑
 const handleSave = () => {
-  handleCancel();
+  const data = [];
+  editData.value.forEach((item) => {
+    data.push(item.video_code_int);
+  });
+  updateUserVideoPoints(data).then(() => {
+    getList();
+    handleCancel();
+  });
 };
 </script>
 
@@ -235,7 +267,6 @@ const handleSave = () => {
 }
 .video-list2 {
   display: flex;
-  justify-content: space-between;
   flex-wrap: wrap;
   padding-top: 100px;
   padding-left: 60px;
@@ -297,4 +328,34 @@ const handleSave = () => {
   width: 190px;
   height: 60px;
 }
+.edit-box {
+  display: flex;
+}
+.box-item {
+  position: relative;
+  margin-left: 20px;
+  .edit-img {
+    width: 200px;
+    height: 100px;
+    background-color: #000;
+  }
+  .edit-title {
+    color: #fff;
+  }
+  .close-btn {
+    position: absolute;
+    top: -20px;
+    right: -20px;
+    cursor: pointer;
+    width: 40px;
+    height: 40px;
+    text-align: center;
+    line-height: 30px;
+    font-size: 40px;
+    font-weight: bold;
+    background-color: #000;
+    border-radius: 50%;
+    color: #fff;
+  }
+}
 </style>

+ 1 - 1
src/views/emergencyCommandMap/RightSection/index.vue

@@ -76,7 +76,7 @@
 
 <script lang="ts" setup>
 import router from '@/router';
-import { getEmergencyVideoCata } from '@/api/routineCommandMap';
+import { getEmergencyVideoCata } from '@/api/videoMonitor';
 import JointDuty from '@/views/emergencyCommandMap/RightSection/JointDuty.vue';
 
 const goToHome = () => {

+ 0 - 2
src/views/globalMap/RightMenu/RoadNetworkVideo.vue

@@ -43,10 +43,8 @@
 
 <script lang="ts" setup>
 import { Search } from '@element-plus/icons-vue';
-import { getEmergencyVideoCata } from '@/api/routineCommandMap';
 import Dialog from '@/components/Dialog/index.vue';
 import { deepClone } from '@/utils';
-import { getWaterList2 } from '@/api/globalMap/reservoir';
 import { getRoadVideoList } from '@/api/globalMap/roadNetworkVideo';
 
 const queryParams = reactive({

+ 5 - 51
src/views/routineCommandMap/RightSection/index.vue

@@ -1,21 +1,6 @@
 <template>
   <div class="right-section">
-    <div class="card">
-      <div class="card-header">
-        <div>视频监控</div>
-        <div class="more" @click="showVideoMonitorList">查看更多</div>
-      </div>
-      <div class="card-content video-list">
-        <div v-for="(item, index) in videoMonitorState.listData" :key="index" class="video-box" @click="showVideoDialog">
-          <div class="video-header">
-            <span>{{ item.name }}</span>
-          </div>
-          <div class="video-content">
-            <HKVideo :dot_data="item" />
-          </div>
-        </div>
-      </div>
-    </div>
+    <VideoMonitor />
     <div class="card">
       <div class="card-header">
         <div>预案管理</div>
@@ -45,13 +30,6 @@
       </div>
     </div>
   </div>
-  <!--视频弹窗-->
-  <!--  <Dialog v-model="videoMonitorState.showDetailDialog" :title="videoMonitorState.detailData.label" width="70%">-->
-  <!--&lt;!&ndash;    <HKVideo :url="videoMonitorState.detailData.url" />&ndash;&gt;-->
-  <!--  </Dialog>-->
-  <Dialog v-model="videoMonitorState.showListDialog" title="视频监控">
-    <videoList />
-  </Dialog>
   <!--预案管理弹窗-->
   <Dialog v-model="planManageState.showListDialog" title="预案管理列表" width="70%">
     <planManageDialog />
@@ -67,27 +45,11 @@
 <script lang="ts" setup name="RightSection">
 
 // 视频监控
-import { getEmergencyPlanList, getEmergencyVideoCata, getReportsList } from '@/api/routineCommandMap';
+import { getEmergencyPlanList, getReportsList } from '@/api/routineCommandMap';
 import KnowledgeDialog from '@/views/routineCommandMap/RightSection/KnowledgeDialog.vue';
 import planManageDialog from '@/views/routineCommandMap/RightSection/planManageDialog.vue';
+import VideoMonitor from '@/views/emergencyCommandMap/LeftSection/VideoMonitor.vue';
 
-// 视频监控
-const videoMonitorState = reactive({
-  listData: [],
-  showListDialog: false,
-  showDetailDialog: false,
-  detailData: { name: '', url: '' }
-});
-
-// 显示视频列表
-const showVideoMonitorList = () => {
-  videoMonitorState.showListDialog = true;
-};
-// 显示视频弹窗
-const showVideoDialog = (item) => {
-  videoMonitorState.detailData = item;
-  videoMonitorState.showDetailDialog = true;
-};
 
 // 预案管理
 const planManageState = reactive({
@@ -132,14 +94,6 @@ const showKnowledgeBaseDetail = () => {
 
 // 初始化数据
 const initData = () => {
-  // 视频监控数据
-  getEmergencyVideoCata({
-    current: 1,
-    size: 6
-  }).then((res) => {
-    videoMonitorState.listData = res.rows;
-    videoMonitorState.listData[0]['video_code'] = '44098102801327000256';
-  });
   // 预案管理数据
   getEmergencyPlanList(planManageState.queryParams).then((res) => {
     res.data.forEach((item) => {
@@ -196,12 +150,12 @@ onMounted(() => {
   }
 
   &:nth-child(2) {
-    height: 667.5px;
+    height: 593px;
     animation-duration: 1s; // 新增
   }
 
   &:nth-child(3) {
-    height: 667.5px;
+    height: 593px;
     animation-duration: 1.5s; // 新增
   }
 }

+ 0 - 149
src/views/videoList/index.vue

@@ -1,149 +0,0 @@
-<template>
-  <div>
-    <div class="form">
-      <el-button type="primary">编辑首页视频</el-button>
-      <div class="form-right">
-        <el-form ref="queryFormRef" :model="formState.queryParams" :inline="true">
-          <el-form-item label="实景视频" prop="videoType">
-            <el-select v-model="formState.queryParams.videoType" placeholder="请选择" clearable>
-              <el-option v-for="dict in formState.options" :key="dict.value" :label="dict.label" :value="dict.value" />
-            </el-select>
-          </el-form-item>
-          <el-form-item prop="name">
-            <el-input v-model="formState.queryParams.name" placeholder="请输入摄像头名称" clearable @keyup.enter="handleQuery" />
-          </el-form-item>
-          <el-form-item>
-            <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
-            <el-button icon="Refresh" @click="resetQuery">重置</el-button>
-          </el-form-item>
-        </el-form>
-      </div>
-    </div>
-    <div class="video-list">
-      <div v-for="(item, index) in formState.listData" :key="index" class="video-box">
-        <div class="video-header">
-          <span>{{ item.label }}</span>
-          <span>{{ item.time }}</span>
-        </div>
-        <div class="video-content">
-          <div v-if="item.checked" class="tip-text">首页展示</div>
-          <video :src="item.url" controls muted style="width: 100%; height: 100%;background: #000;" />
-        </div>
-      </div>
-    </div>
-    <div style="width: 100%;display: flex;justify-content: center;">
-      <pagination
-        :total="formState.total"
-        :page="formState.queryParams.page"
-        :limit="formState.queryParams.limit"
-        @pagination="getList"
-      />
-    </div>
-  </div>
-</template>
-
-<script lang="ts" setup>
-const queryFormRef = ref<ElFormInstance>();
-const formState = reactive({
-  queryParams: {
-    videoType: '',
-    name: '',
-    page: 1,
-    limit: 10
-  },
-  total: 100,
-  options: [
-    { label: '全景视频', value: '1' },
-    { label: '普通视频', value: '2' }
-  ],
-  listData: [],
-  activeIds: []
-});
-
-const getList = () => {
-  const listData = [
-    { id: 1, label: '摄像头一', img: '', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
-    { id: 2, label: '摄像头二', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
-    { id: 3, label: '摄像头三', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
-    { id: 4, label: '摄像头四', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
-    { id: 5, label: '摄像头五', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
-    { id: 6, label: '摄像头六', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
-    { id: 7, label: '摄像头七', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
-    { id: 8, label: '摄像头八', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
-    { id: 9, label: '摄像头九', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
-    { id: 10, label: '摄像头十', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' }
-  ];
-  formState.activeIds = [1, 2, 3, 4, 6, 7];
-  listData.forEach((item) => {
-    const index = formState.activeIds.findIndex((item2) => item2 === item.id);
-    item.checked = index > -1;
-  });
-  formState.listData = listData;
-};
-
-const handleQuery = () => {
-
-};
-/** 重置按钮操作 */
-const resetQuery = () => {
-  queryFormRef.value?.resetFields();
-  handleQuery();
-};
-
-onMounted(() => {
-  getList();
-});
-</script>
-
-<style lang="scss" scoped>
-.form {
-  display: flex;
-  justify-content: space-between;
-}
-.video-list {
-  display: flex;
-  flex-wrap: wrap;
-  .video-box {
-    width: 943px;
-    margin-right: 46px;
-    &:nth-child(1),
-    &:nth-child(2),
-    &:nth-child(3),
-    &:nth-child(4),
-    &:nth-child(5) {
-      margin-bottom: 15px;
-    }
-    &:nth-child(5),
-    &:nth-child(10) {
-      margin-right: 0;
-    }
-  }
-}
-.video-box {
-  cursor: pointer;
-  .video-header {
-    background-color: #7f7f7f;
-    padding: 0 10px;
-    font-size: 30px;
-    color: #fff;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-  }
-  .video-content {
-    padding: 15px;
-    background-color: #ccc;
-    height: 600px;
-    position: relative;
-    .tip-text {
-      position: absolute;
-      top: 0;
-      left: 0;
-      background-color: #ec808d;
-      color: #fff;
-      font-size: 32px;
-      padding: 15px 40px;
-    }
-  }
-}
-</style>