Просмотр исходного кода

Merge branch 'dev'

# Conflicts:
#	src/components/HeaderSection/index.vue
Hwf 9 месяцев назад
Родитель
Сommit
e7bfbcdeb0

+ 4 - 1
index.html

@@ -5,7 +5,10 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
     <meta name="renderer" content="webkit" />
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
-    <link rel="icon" href="/favicon.ico" />
+<!--    <link rel="icon" href="/favicon.ico" />-->
+    <script src="/h5player.min.js"></script>
+    <script src="/Decoder.js"></script>
+
     <title>应急指挥一张图</title>
     <!--[if lt IE 11
       ]><script>

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
public/Decoder.js


Разница между файлами не показана из-за своего большого размера
+ 5 - 0
public/h5player.min.js


+ 60 - 0
src/components/Dialog/index.vue

@@ -0,0 +1,60 @@
+<template>
+  <div class="overlay">
+    <div class="dialog">
+      <div class="dialog-header">
+        <div class="dialog-title"></div>
+        <div class="icon-close">
+          <el-icon size="100px"><Close /></el-icon>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+interface Props {
+  visible: boolean;
+  title?: string;
+}
+const props = withDefaults(defineProps<Props>(), {
+  visible: false
+});
+</script>
+
+<style lang="scss" scoped>
+.overlay {
+  position: fixed;
+  top: 0;
+  right: 0;
+  left: 0;
+  bottom: 0;
+  z-index: 2000;
+  background-color: rgba(0, 0, 0, 0.5);
+  width: 100%;
+  height: 100%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  .dialog {
+    width: 5000px;
+    height: 2000px;
+    margin: 0 auto;
+    background-color: #fff;
+    border-radius: 20px;
+  }
+}
+.dialog {
+  padding: 0 50px;
+  .dialog-header {
+    width: 100%;
+    height: 150px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .icon-close {
+      cursor: pointer;
+    }
+  }
+
+}
+</style>

+ 106 - 0
src/components/HKVideo/index.vue

@@ -0,0 +1,106 @@
+<template>
+  <div id="HKVideo" class="HKVideo1"></div>
+</template>
+
+<script lang="ts" setup>
+interface Props {
+  url: string;
+}
+const props = withDefaults(defineProps<Props>(), {});
+//下方为海康视频播放器所需变量
+const oPlugin = ref();
+let time;
+
+async function getScript() {
+  const { JSPlugin }: any = window;
+  oPlugin.value = new JSPlugin({
+    szId: 'HKVideo', // 当前的视频播放的节点,需要英文字母开头,必填
+    szBasePath: '/', // 这里必须指向h5player.min.js文件 把这个文件再放在src里面的一个文件夹中,因为放置在public的文件这里指向不到
+    openDebug: true,
+    // 分屏播放
+    iMaxSplit: 4,
+    iCurrentSplit: 1,
+    // 设置样式
+    oStyle: {
+      border: '#FFF',
+      borderSelect: '#FFCC00',
+      background: '#000'
+    }
+  });
+
+  await initPlugin();
+}
+
+// 事件初始化
+function initPlugin() {
+  oPlugin.value.JS_SetWindowControlCallback({
+    windowEventSelect(iWindIndex: any) {
+      // 插件选中窗口回调
+      console.log('windowSelect callback: ', iWindIndex);
+    },
+    pluginErrorHandler(iWindIndex: any, iErrorCode: any, oError: any) {
+      // 插件错误回调
+      console.error(`window-${iWindIndex}, errorCode: ${iErrorCode}`, oError);
+    },
+    windowEventOver(iWindIndex: any) {
+      // 鼠标移过回调
+      console.log('鼠标移过回调', iWindIndex);
+    },
+    windowEventOut(iWindIndex: any) {
+      // 鼠标移出回调
+      console.log('鼠标移出回调', iWindIndex);
+    },
+    windowFullCcreenChange(bFull: any) {
+      // 全屏切换回调
+      console.log('全屏切换回调', bFull);
+    },
+    firstFrameDisplay(iWndIndex: any, iWidth: any, iHeight: any) {
+      // 首帧显示回调
+      console.log('首帧显示回调', iWndIndex, iWidth, iHeight);
+    },
+    performanceLack(iWndIndex: any) {
+      // 性能不足回调
+      console.log('性能不足回调', iWndIndex);
+    }
+  });
+  realplay();
+}
+
+//   // 播放初始化
+function realplay() {
+  console.log('播放初始化');
+  console.log(oPlugin.value.currentWindowIndex, 'oPlugin.value.currentWindowIndex');
+  oPlugin.value
+    .JS_Play(
+      props.url, //视频地址链接
+      {
+        playURL: 'props.url' // 流媒体播放时必传
+      },
+      oPlugin.value.currentWindowIndex //这个应该是视频下标吧 具体我也不太清楚
+    )
+    .then(
+      (res: any) => {
+        console.log(res, '播放成功');
+      },
+      (err: any) => {
+        console.log(err, '播放失败');
+      }
+    );
+}
+
+onMounted(async () => {
+  time = setInterval(() => {
+    const { _malloc }: any = window;
+    if (_malloc) {
+      getScript();
+      clearInterval(time);
+    }
+  }, 100);
+});
+</script>
+
+<style lang="scss" scoped>
+.HKVideo1 {
+  width: 100%;
+}
+</style>

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

@@ -1,7 +1,7 @@
 <template>
   <div class="headerSection">
     <div class="header-left">
-      <el-button class="custom-button" type="primary">全景地图</el-button>
+      <el-button class="custom-button" type="primary" @click="jumpGlobeMap">全景地图</el-button>
     </div>
     <div class="header-middle">
       <div class="header-title">应急指挥一张图</div>

+ 61 - 0
src/components/Map/index.vue

@@ -0,0 +1,61 @@
+<template>
+  <div class="map-container">
+    <div :id="mapid"
+         class="map-container"></div>
+  </div>
+</template>
+<script>
+
+export default {
+  name: 'Map',
+  props: {
+    mapid: {
+      type: String,
+      default: 'map'
+    }
+  },
+  data() {
+    return {};
+  },
+  computed: {},
+  watch: {},
+  mounted() {
+    this.initMapEvent();
+  },
+  beforeDestroy() {},
+  methods: {
+    initMapEvent() {
+      const that = this;
+      let simple = {
+        version: 8,
+        sources: {},
+        layers: []
+      };
+      let wgs84_wgs84_mapcrs = {
+        topTileExtent: [-180, -270, 180, 90],
+        coordtransform: "none",
+        tileSize: 256
+      };
+      const map = new GeoGlobe.Map({
+        mapCRS: wgs84_wgs84_mapcrs,
+        style: simple,
+        maxZoom: 20,
+        zoom: 7,
+        minZoom: 7,
+        center: [113.272753, 23.139257],
+        container: "map"
+      });
+      map.on("style.load", function(e) {
+        that.$emit("getmap", map);
+      });
+    }
+
+  }
+};
+</script>
+<style scoped>
+.map-container {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 3 - 1
src/components/ScrollTable/index.vue

@@ -7,7 +7,7 @@
         </tr>
       </thead>
       <tr class="tr">
-        <td v-for="(item, index) in dataSource" :key="index" class="td">{{ item.label }}</td>
+        <td v-for="(item, index) in dataSource" :key="index" class="td">{{ item.name }}</td>
       </tr>
     </table>
   </div>
@@ -20,6 +20,7 @@ interface Columns {
 interface Props {
   columns: Array<Columns>;
   dataSource: any[];
+  labelName: 'label';
 }
 const props = withDefaults(defineProps<Props>(), {});
 </script>
@@ -38,6 +39,7 @@ const props = withDefaults(defineProps<Props>(), {});
     }
     .tr {
       .td {
+        width: auto;
         font-size: 42px;
         padding: 37px 14px;
       }

+ 6 - 1
src/router/index.ts

@@ -74,7 +74,12 @@ export const constantRoutes: RouteRecordRaw[] = [
         meta: { title: '个人中心', icon: 'user' }
       }
     ]
-  }
+  },
+  {
+    path: '/index',
+    component: () => import('@/views/dashboard/index.vue'),
+    name: 'Index'
+  },
 ];
 
 // 动态路由,基于用户权限动态去加载

+ 41 - 12
src/views/dashboard/LeftSection.vue

@@ -15,7 +15,21 @@
         <div>巡查消息</div>
       </div>
       <div class="card-content">
-        <ScrollTable :columns="columns" :data-source="listData" />
+        <table class="table">
+          <thead>
+            <tr class="tr">
+              <td v-for="(item, index) in columns" :key="index" class="td">{{ item.label }}</td>
+            </tr>
+          </thead>
+          <tr v-for="(item, index) in listData" :key="index" class="tr">
+            <td class="td">{{ item.name }}</td>
+            <td class="td">{{ item.type }}</td>
+            <td class="td">{{ item.address }}</td>
+            <td class="td">{{ item.time }}</td>
+            <td class="td">{{ item.result }}</td>
+            <td class="td">{{ item.img }}</td>
+          </tr>
+        </table>
       </div>
     </div>
     <div class="card">
@@ -23,7 +37,7 @@
         <div>事件接报</div>
       </div>
       <div class="card-content flex" style="height: 100%">
-        <Chart :option="option1" />
+        <!--<Chart :option="option1" />-->
       </div>
     </div>
   </div>
@@ -42,16 +56,12 @@ const columns = [
   { label: '巡检图像', key: 'img' }
 ];
 const listData = reactive([
-  { name: '巡检任务1', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' },
-  { name: '巡检任务2', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' },
-  { name: '巡检任务3', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' },
-  { name: '巡检任务4', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' },
-  { name: '巡检任务5', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' },
-  { name: '巡检任务6', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' },
-  { name: '巡检任务7', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' },
-  { name: '巡检任务8', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' },
-  { name: '巡检任务9', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' },
-  { name: '巡检任务10', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常' }
+  { name: '巡检任务1', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常', img: '' },
+  { name: '巡检任务2', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常', img: '' },
+  { name: '巡检任务3', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常', img: '' },
+  { name: '巡检任务4', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常', img: '' },
+  { name: '巡检任务5', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常', img: '' },
+  { name: '巡检任务6', type: '城市隐患巡查', address: '油城十路', time: '2024-7-11 16:00:21', result: '正常', img: '' }
 ]);
 
 // 事件接报
@@ -91,6 +101,25 @@ const option1 = reactive(chartOption1);
     animation-duration: 1.5s; // 新增
   }
 }
+.table {
+  table-layout: fixed;
+  border-collapse: collapse;
+  width: 100%;
+  thead {
+    .td {
+      background-color: #fafafa;
+      border: 5px solid #ebebeb;
+    }
+  }
+  .tr {
+    .td {
+      width: auto;
+      font-size: 28px;
+      padding: 10px 5px;
+      border-bottom: 5px solid #ebebeb;
+    }
+  }
+}
 @keyframes slide {
   0% {
     transform: translateX(-100%);

+ 92 - 5
src/views/dashboard/RightSection.vue

@@ -2,12 +2,19 @@
   <div class="right-section">
     <div class="card">
       <div class="card-header">
-        <div>综合值守</div>
+        <div>视频监控</div>
+        <div class="more">查看更多</div>
       </div>
-      <div class="card-content">
-        <div style="line-height: 207px">值班时间:08-30-17:30</div>
-        <div style="line-height: 207px">带班领导:张珊珊</div>
-        <div style="line-height: 207px">值班时间:林珊珊、张珊珊</div>
+      <div class="card-content video-list">
+        <div v-for="(item, index) in videoUrl" :key="index" class="video-box" @click="showVideoDialog(item)">
+          <div class="video-header">
+            <span>{{ item.label }}</span>
+            <span>{{ item.time }}</span>
+          </div>
+          <div class="video-content">
+            <img class="img" src="@/assets/images/profile.jpg" alt="" />
+          </div>
+        </div>
       </div>
     </div>
     <div class="card">
@@ -23,10 +30,39 @@
       <div class="card-content"></div>
     </div>
   </div>
+  <!--视频弹窗-->
+  <!--  <Dialog v-model="videoDialogVisible" :title="videoDialogData.label" width="70%" :before-close="handleClose">-->
+  <!--    <HKVideo :url="videoDialogData.url" />-->
+  <!--  </Dialog>-->
 </template>
 
 <script lang="ts" setup>
+import Dialog from '@/components/Dialog/index.vue';
+import HKVideo from '@/components/HKVideo/index.vue';
 
+// 视频监控
+const videoUrl = reactive([
+  { label: '摄像头一', img: '', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
+  { label: '摄像头二', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
+  { label: '摄像头三', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
+  { label: '摄像头四', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
+  { label: '摄像头五', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' },
+  { label: '摄像头六', url: 'https://vjs.zencdn.net/v/oceans.mp4', time: '17:14' }
+]);
+// 视频弹窗显隐
+let videoDialogVisible = ref(false);
+let videoDialogData = reactive({});
+
+// 显示视频弹窗
+const showVideoDialog = (item) => {
+  console.log(item);
+  videoDialogData = item;
+  videoDialogVisible.value = true;
+};
+// 关闭视频弹窗
+const handleClose = () => {
+  videoDialogVisible.value = false;
+};
 </script>
 
 <style lang="scss" scoped>
@@ -37,6 +73,7 @@
   flex-direction: column;
   font-size: 74px;
 }
+
 .card {
   width: 100%;
   background-color: #ffffff;
@@ -44,21 +81,33 @@
   padding: 46px 69px;
   margin-bottom: 69px;
   animation-name: slide;
+
+  .card-header {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
   &:last-child {
     margin-bottom: 0;
   }
+
   &:nth-child(1) {
     animation-duration: 0.5s; // 新增
   }
+
   &:nth-child(2) {
     height: 667.5px;
     animation-duration: 1s; // 新增
   }
+
   &:nth-child(3) {
     height: 667.5px;
     animation-duration: 1.5s; // 新增
   }
 }
+
 @keyframes slide {
   0% {
     transform: translateX(100%);
@@ -70,4 +119,42 @@
     transform: translateX(0);
   }
 }
+
+.more {
+  color: #1890ff;
+  cursor: pointer;
+}
+
+.video-list {
+  display: flex;
+  flex-wrap: wrap;
+  .video-box {
+    width: 485px;
+    margin-right: 46px;
+    &:nth-child(3),
+    &:nth-child(6) {
+      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;
+    .img {
+      width: 100%;
+      height: 250px;
+    }
+  }
+}
 </style>

+ 9 - 9
src/views/dashboard/index.vue

@@ -16,15 +16,15 @@ import MiddleSection from '@/views/dashboard/MiddleSection.vue';
 import autofit from 'autofit.js';
 
 onMounted(() => {
-  autofit.init(
-    {
-      dw: 8960,
-      dh: 2520,
-      el: '#dashboard-container',
-      resize: true
-    },
-    false
-  );
+  // autofit.init(
+  //   {
+  //     dw: 8960,
+  //     dh: 2520,
+  //     el: '#dashboard-container',
+  //     resize: true
+  //   },
+  //   false
+  // );
 });
 
 onUnmounted(() => {

+ 9 - 0
src/views/globalMap/index.vue

@@ -0,0 +1,9 @@
+<template>
+  <Map></Map>123
+</template>
+
+<script lang="ts" setup>
+import Map from '@/components/Map/index.vue';
+</script>
+
+<style lang="scss" scoped></style>

Некоторые файлы не были показаны из-за большого количества измененных файлов