瀏覽代碼

左下角门禁记录修改

huangyan 9 月之前
父節點
當前提交
82fcda8b6d

+ 4 - 38
index.html

@@ -1,49 +1,15 @@
 <!DOCTYPE html>
 <html lang="en">
-
 <head>
   <meta charset="UTF-8" />
   <link rel="icon" href="/favicon.ico" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <script type="importmap">
-        {
-    "imports": {
-      "three": "./public/archive/static/build/three.module.js",
-      "three/addons/": "./public/archive/static/js/jsm/",
-      "three/libs/": "./public/archive/static/js/libs/"
-    }
-  }
-    </script>
-    <style>
-        body {
-            font-family: sans-serif;
-            font-size: 11px;
-            background-color: #000;
-            margin: 0px;
-        }
-
-        canvas {
-            display: block;
-        }
-    </style>
-    <script src="./public/archive/static/js/jquery.min.js"></script>
-
-    <title>IofTV-Screen-Vue3</title>
-
+  <title>一体化可视平台</title>
 </head>
-
 <body>
   <div id="app"></div>
   <script type="module" src="/src/main.ts"></script>
-  <!-- 3D 1v -->
-  <script type="module" src="./public/archive/static/build/IOT3D.js"></script>
-
-  <link rel="stylesheet" href="./public/archive/static/js/libs/loading/load.css" media="all">
-  <script async src="./public/archive/static/js/libs/loading/load.js" charset="utf-8"></script>
-<!--  <script src="./public/archive/static/editor/lib/lib.js"></script>   &lt;!&ndash;  物联智控核心  &ndash;&gt;-->
-
-  <!-- 3D 1v -->
+  <script type="text/javascript" src="/src/webrtc/webrtcstreamer.js"></script>
+  <script type="text/javascript" src="/src/webrtc/adapter.min.js"></script>
 </body>
-<script type="text/javascript" src="/src/webrtc/webrtcstreamer.js"></script>
-<script type="text/javascript" src="/src/webrtc/adapter.min.js"></script>
-</html>
+</html>

+ 0 - 47
public/archive/LoadLocal.html

@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-	<title>宝智达 • 3D数字孪生平台</title>
-	<meta charset="utf-8">
-	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-	<link rel="shortcut icon" href="./favicon.ico">
-	<style>
-		body {
-			font-family: sans-serif;
-			font-size: 11px;
-			background-color: #000;
-			margin: 0px;
-		}
-
-		canvas {
-			display: block;
-		}
-	</style>
-	<script src="./static/js/jquery.min.js"></script>
-</head>
-
-<body>
-<div id="iot3d" style="height: 80%; width: 80%;"></div>
-<!-- Import maps polyfill -->
-<!-- Remove this when import maps will be widely supported "three": "./build/three.module.js",  -->
-<script async src="./static/build/es-module-shims.js"></script>
-
-<script type="importmap">
-			{
-				"imports": {
-					"three": "./static/build/three.module.js",
-					"three/addons/": "./static/js/jsm/",
-					"three/libs/": "./static/js/libs/"
-				}
-			}
-</script>
-
-<script type="module" src="./static/build/IOT3D.js"></script>
-
-<link rel="stylesheet" href="./static/js/libs/loading/load.css" media="all">
-<script async src="./static/js/libs/loading/load.js" charset="utf-8"></script>
-<!--<script src="./static/editor/lib/lib.js"></script>   &lt;!&ndash;  物联智控核心  &ndash;&gt;-->
-
-
-</body>
-</html>

+ 0 - 67
public/archive/static/js/libs/loading/index.html

@@ -1,67 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta charset="UTF-8">
-		<title></title>
-		<script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
-		<link rel="stylesheet" href="load.css"  media="all">
-		<script src="load-min.js" charset="utf-8"></script>
-		<style>
-			button{
-				outline: none;
-				padding: 5px 15px;
-				border: 1px solid #eee;
-				background-color: #FFFFFF;
-				border-radius: 5px;
-				font-size: 12px;
-			}
-			button:hover{
-				cursor: pointer;
-			}
-			
-			.test_mask{
-				width: 800px;
-				height: 300px;
-				border: 1px solid #BCE8F1;
-			}
-		</style>
-	</head>
-	<body>
-			<button onclick="mask_fullscreen()">数据加载-全屏(1s自动关闭)</button>
-			<button onclick="mask_element()">数据加载-指定元素(3s自动关闭)</button>
-			<button onclick="mask_element_continuious()">数据加载-指定元素(不自动关闭)</button>
-			<button onclick="mask_close()">关闭指定元素加载层</button>
-			<button onclick="mask_close_all()">关闭所有加载层</button>
-			<hr />
-			<div>自动关闭:</div>
-			<div id = "test_mask" class="test_mask">
-			</div>
-			<br>
-			<div>不自动关闭:</div>
-			<div id = "test_mask_2" class="test_mask">
-			</div>
-	</body>
-	<script type="text/javascript">
-		//加载层-全屏
-		function mask_fullscreen(){
-			$.mask_fullscreen(1000);
-			
-		}
-		//加载层-指定元素
-		function mask_element(){
-			$.mask_element('#test_mask', 3000);
-		}
-		//加载层-指定元素:不自动关闭
-		function mask_element_continuious(){
-			$.mask_element('#test_mask_2');
-		}
-		//关闭指定元素加载层
-		function mask_close(){
-			$.mask_close('#test_mask_2');
-		}
-		//关闭所有加载层
-		function mask_close_all(){
-			$.mask_close_all();
-		}
-	</script>
-</html>

+ 6 - 6
src/api/api.ts

@@ -1,11 +1,12 @@
+import type {AxiosRequestConfig, AxiosResponse} from "axios";
 import axios from "axios";
-import type { AxiosRequestConfig, AxiosResponse } from "axios";
-import { StorageEnum, RequestEnum } from "@/enums";
-import { getLocalStorage } from "@/utils";
+import {StorageEnum} from "@/enums";
+import {getLocalStorage} from "@/utils";
 
 import UtilVar from "../config/UtilVar";
-import { ElMessage } from "element-plus";
+import {ElMessage} from "element-plus";
 import router from "@/router";
+
 let baseUrl = UtilVar.baseUrl;
 // let baseUrl = "/api";
 const CancelToken = axios.CancelToken;
@@ -19,11 +20,10 @@ axios.interceptors.request.use(
       return config;
     }
     // 在发送请求之前做些什么 传token
-    let token: any = getLocalStorage(StorageEnum.GB_TOKEN_STORE);
     // console.log(token);
     // if (token) {
       // @ts-ignore
-      config.headers['Authorization'] = token;
+      config.headers['Authorization'] = getLocalStorage(StorageEnum.GB_TOKEN_STORE);
     // }
     // @ts-ignore
     config.headers["Content-Type"] = "application/json;charset=utf-8";

+ 26 - 26
src/assets/css/main.scss

@@ -22,32 +22,32 @@ body {
   z-index: 1;
 }
 //3d模型
-#iot3d {
-  position: absolute;
-  top: 3%;
-  left: 25%;
-  transform: translate(0, 0);
-  // border: 5px solid rgba(247, 0, 0, 0.5);
-  margin-top: 5vh;
-  width: 50%;
-  height: 55vh;
-}
-
-#iot3d>div,
-#iot3d>canvas {
-  position: absolute;
-  top: 0;
-  left: 50;
-  width: 100% !important;
-  height: 100% !important;
-  // border: #059465 solid 5px;
-}
-//加载动画样式
-#lot3d_loading_mask_html {
-  font-size: larger;
-  z-index: 9999;
-  background-color: rgba(255, 255, 255, 0.8);
-}
+//#iot3d {
+//  position: absolute;
+//  top: 3%;
+//  left: 25%;
+//  transform: translate(0, 0);
+//  // border: 5px solid rgba(247, 0, 0, 0.5);
+//  margin-top: 5vh;
+//  width: 50%;
+//  height: 55vh;
+//}
+//
+//#iot3d>div,
+//#iot3d>canvas {
+//  position: absolute;
+//  top: 0;
+//  left: 50;
+//  width: 100% !important;
+//  height: 100% !important;
+//  // border: #059465 solid 5px;
+//}
+////加载动画样式
+//#lot3d_loading_mask_html {
+//  font-size: larger;
+//  z-index: 9999;
+//  background-color: rgba(255, 255, 255, 0.8);
+//}
 
 html .el-message {
   --yh-bg-color-container: #242424;

+ 6 - 0
src/router/index.ts

@@ -62,6 +62,12 @@ const routes: Array<RouteRecordRaw> = [
         meta: { requiresAuth: true },
       },
       {
+        path: '/Load3D',
+        name: 'Load3D',
+        component: () => import('@/views/index/Load3D.vue'),
+        meta: { requiresAuth: true },
+      },
+      {
         path: '/login',
         name: 'login',
         component: Login,

+ 11 - 0
src/views/index/Load3D.vue

@@ -0,0 +1,11 @@
+<script setup lang="ts">
+
+</script>
+
+<template>
+  <iframe src="public/LoadLocal.html" style="width: 100%; height: 100%;" />
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 69 - 30
src/views/index/index.vue

@@ -1,6 +1,7 @@
 <template>
   <div class="index-box">
-    <div class="contetn_left">
+    <transition name="fade">
+    <div  v-if="!isFullScreen" class="contetn_left">
       <ItemWrap class="contetn_left-top contetn_lr-item" title="档案在位情况">
         <LeftTop />
       </ItemWrap>
@@ -11,22 +12,25 @@
         <LeftBottom />
       </ItemWrap>
     </div>
-    <div  class="contetn_center" id="contetn_center">
-      <Iot3d v-if="shouldShowComponent" style="z-index:200"  />
+    </transition>
+    <div class="contetn_center" :class="{'is-fullscreen': isFullScreen }">
+      <Load3D></Load3D>
     </div>
-    <div class="contetn_centerbottom">
+    <transition name="fade">
+    <div v-if="!isFullScreen" class="contetn_centerbottom">
       <ItemWrap class="contetn_center-bottom contetn_lr-item" title="视频监控">
-        <!-- <CenterBottom /> -->
-<!--         <Monitor></Monitor>-->
-         <div class="monitor-container">
-        <div class="monitor"  v-for="(stream, index) in stream_url">
+        <n-carousel autoplay show-arrow :per-view="2" interval="5000">
+        <div class="monitor-container"  v-for="(group, groupIndex) in groupedStreams" :key="groupIndex">
+        <div class="monitor"  v-for="(stream, index) in group">
           <webrtc :key="stream.id" :streamurl="stream.url" :videoId="'video-' + index"></webrtc>
         </div>
-      </div>
+        </div>
+        </n-carousel>
       </ItemWrap>
     </div>
+    </transition>
     <div class="contetn_bottom" id="contetn_bottom">
-      <n-button strong secondary type="info" class="tech-button" tag="a" @click="$router.push('/archives')">全屏展示
+      <n-button strong secondary type="info" class="tech-button" tag="a" @click="toggleFullScreen">全屏展示
         <template #icon>
           <n-icon size="20">
             <img src="@/assets/img/full.svg">
@@ -71,7 +75,8 @@
         </template>
       </n-button>
     </div>
-    <div class="contetn_right">
+    <transition name="fade">
+    <div v-if="!isFullScreen" class="contetn_right">
       <ItemWrap class="contetn_left-bottom contetn_lr-item"  title="温湿度实时曲线">
         <RightTop />
       </ItemWrap>
@@ -82,10 +87,11 @@
         <RightBottom />
       </ItemWrap>
     </div>
+    </transition>
   </div>
 </template>
 <script setup lang="ts">
-import { ref } from 'vue'
+import { ref,computed } from 'vue'
 import ItemWrap from "@/components/item-wrap";
 import LeftTop from "./left-top.vue";
 import LeftCenter from "./left-center.vue";
@@ -94,25 +100,36 @@ import RightTop from "./right-top.vue";
 import RightCenter from "./right-center.vue";
 import RightBottom from "./right-bottom.vue";
 import webrtc from './webrtc.vue';
-import { NIcon } from "naive-ui";
+import { NIcon,NCarousel } from "naive-ui";
 import Iot3d from "./iot3d.vue";
 import { onBeforeRouteLeave } from 'vue-router';
 import WebH5 from './webH5.vue';
 import Monitor from './monitor.vue';
 import { id } from 'element-plus/es/locale';
+import Load3D from "@/views/index/Load3D.vue";
 const shouldShowComponent = ref(true);
 
 let stream_url = ref([
   { id: 1, url: 'rtsp://admin:jxzs12345@192.168.1.2:554/h264/ch1/main/av_stream' },
   { id: 2, url: 'rtsp://admin:jxzs12345@192.168.1.3:554/h264/ch1/main/av_stream' },
-  // { id: 3, url: 'rtsp://admin:jxzs12345@192.168.1.4:554/h264/ch1/main/av_stream' },
-  // { id: 4, url: 'rtsp://admin:jxzs12345@192.168.1.5:554/h264/ch1/main/av_stream' },
-  // { id: 5, url: 'rtsp://admin:jxzs12345@192.168.1.6:554/h264/ch1/main/av_stream' },
-  // { id: 6, url: 'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream' },
-  // { id: 7, url: 'rtsp://admin:jxzs12345@192.168.1.8:554/h264/ch1/main/av_stream' },
-  // { id: 8, url: 'rtsp://admin:jxzs12345@192.168.1.64:554/h264/ch1/main/av_stream' },
+  { id: 3, url: 'rtsp://admin:jxzs12345@192.168.1.4:554/h264/ch1/main/av_stream' },
+  { id: 4, url: 'rtsp://admin:jxzs12345@192.168.1.5:554/h264/ch1/main/av_stream' },
+  { id: 5, url: 'rtsp://admin:jxzs12345@192.168.1.6:554/h264/ch1/main/av_stream' },
+  { id: 6, url: 'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream' },
+  { id: 7, url: 'rtsp://admin:jxzs12345@192.168.1.8:554/h264/ch1/main/av_stream' },
+  { id: 8, url: 'rtsp://admin:jxzs12345@192.168.1.64:554/h264/ch1/main/av_stream' },
 ]);
-
+const isFullScreen = ref(false);
+const toggleFullScreen = () => {
+  isFullScreen.value = !isFullScreen.value;
+};
+const groupedStreams = computed(() => {
+  const groups = [];
+  for (let i = 0; i < stream_url.value.length; i += 2) {
+    groups.push(stream_url.value.slice(i, i + 2));
+  }
+  return groups;
+});
 onBeforeRouteLeave((to, from, next) => {
   shouldShowComponent.value = false;
   next();
@@ -120,7 +137,6 @@ onBeforeRouteLeave((to, from, next) => {
 
 </script>
 
-
 <style scoped lang="scss">
 .index-box {
   width: 100%;
@@ -149,13 +165,25 @@ onBeforeRouteLeave((to, from, next) => {
   width: 440px;
 }
 
-
 .contetn_center {
   display: flex;
   align-items: center;
   justify-content: center;
+  //border: 1px solid #e3b337; /* 默认边框样式 */
+}
+
+/* 全屏时的样式 */
+.contetn_center.is-fullscreen{
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100% !important;
+  height: 920px !important;
+  z-index: 1000;
+  //border: 1px solid #e3378d; /* 全屏时的边框样式 */
 }
 
+
 .contetn_lr-item {
   height: 310px;
   font-size: large;
@@ -165,14 +193,11 @@ onBeforeRouteLeave((to, from, next) => {
   width: 100%;
   margin-top: auto;
   position: absolute;
-  /* 添加绝对定位 */
   bottom: 0;
   display: flex;
   justify-content: center;
   transform: translateY(-10px);
-  /* 向上“浮动”10px */
   transition: transform 0.3s ease;
-  /* 添加过渡效果 */
 }
 
 .tech-button {
@@ -200,22 +225,36 @@ onBeforeRouteLeave((to, from, next) => {
   margin-top: -55px;
   font-size: large;
 }
-.index-box{
+
+.index-box {
   z-index: 1000000 !important;
 }
+
 .monitor {
   margin-left: 10px;
   width: 50% !important;
   height: 100% !important;
-  // border: #ffea00 solid 1px;
 }
-.monitor-container{
+
+.monitor-container {
   width: 100% !important;
   height: 100% !important;
   display: flex;
 }
-.fullscreen{
+
+.fullscreen {
   margin-top: -50px;
   margin-left: 350px;
 }
-</style>
+
+/* 过渡效果 */
+.fade-enter-active,
+.fade-leave-active {
+  transition: opacity 0.3s;
+}
+
+.fade-enter-from,
+.fade-leave-to {
+  opacity: 0;
+}
+</style>

+ 96 - 30
src/views/index/left-bottom.vue

@@ -1,11 +1,12 @@
 <script setup lang="ts">
 import { leftBottom } from "@/api";
 import SeamlessScroll from "@/components/seamless-scroll";
-import { computed, onMounted, reactive } from "vue";
+import {computed, onMounted, reactive, ref} from "vue";
 import { useSettingStore } from "@/stores";
 import { storeToRefs } from "pinia";
 import EmptyCom from "@/components/empty-com";
 import { ElMessage } from "element-plus";
+import {GetMonitor} from "api/modules/monitor";
 
 const settingStore = useSettingStore();
 const { defaultOption, indexConfig } = storeToRefs(settingStore);
@@ -18,25 +19,88 @@ const state = reactive<any>({
   },
   scroll: true,
 });
-const listtest=['测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一','测试一']
-const getData = () => {
-  // leftBottom( { limitNum: 20 })
-  //   .then((res) => {
-  //     console.log("左下--设备提醒", res);
-  //     if (res.success) {
-  //       state.list = res.data.list;
-  //     } else {
-  //       ElMessage({
-  //         message: res.msg,
-  //         type: "warning",
-  //       });
-  //     }
-  //   })
-  //   .catch((err) => {
-  //     ElMessage.error(err);
-  //   });
-  state.list=listtest
-};
+let monitor = ref([{
+  id: '',
+  faceImagePath: '',
+  majorEventType: '',
+  subEventType: '',
+  CreatedAt: '',
+  ipAddress:''
+}])
+const userform = reactive({
+  "page": 1,
+  "size": 10,
+  "startTime": "",
+  "endTime": "",
+  "desc": "created_at desc"
+});
+const isLoading = ref(false);
+let page_count = ref(0);
+
+// function formatState(row, column, cellValue, index) {
+//   switch (cellValue) {
+//     case 75:
+//       return "验证通过";
+//     case 76:
+//       return "验证失败";
+//     default:
+//       return "未知";
+//   }
+// }
+function formatState(majorEventType:any) {
+  switch (majorEventType) {
+    case 75:
+      return "通过";
+    case 76:
+      return "失败";
+    default:
+      return "未知";
+  }
+}
+function formalocation(row:any, column:any, cellValue:any, index:any) {
+  switch (cellValue) {
+    case '192.168.1.103':
+      return "二楼门禁";
+    case '192.168.1.104':
+      return "四楼门禁";
+    default:
+      return "未知";
+  }
+}
+function formatmonitor(row:any, column:any, cellValue:any, index:any) {
+  switch (cellValue) {
+    case 5:
+      return "人脸验证";
+    case 6:
+      return "四楼门禁";
+    default:
+      return "未知";
+  }
+}
+function formatDate(date:any, format:any) {
+  let map = {
+    'yyyy': date.getFullYear(),
+    'MM': ('0' + (date.getMonth() + 1)).slice(-2),
+    'dd': ('0' + date.getDate()).slice(-2),
+    'HH': ('0' + date.getHours()).slice(-2),
+    'mm': ('0' + date.getMinutes()).slice(-2),
+    'ss': ('0' + date.getSeconds()).slice(-2)
+  };
+  return format.replace(/(yyyy|MM|dd|HH|mm|ss)/g, (match:any) => map[match]);
+}
+//获取最新门禁记录
+function getStockRecord() {
+  isLoading.value = true;
+  GetMonitor(userform).then(res => {
+    if (res.code === 200) {
+      monitor.value=res.data.result
+      page_count.value = res.data.total;
+      isLoading.value = false;
+      state.list=monitor.value
+    }
+  })
+}
+
 const addressHandle = (item: any) => {
   let name = item.provinceName;
   if (item.cityName) {
@@ -54,11 +118,14 @@ const comName = computed(() => {
     return EmptyCom;
   }
 });
+const startPolling = () => {
+  getStockRecord();
+  setInterval(getStockRecord, 5000); // 每5秒轮询一次
+};
 onMounted(() => {
-  getData();
+  startPolling();
 });
 </script>
-
 <template>
   <div class="left_boottom_wrap beautify-scroll-def" :class="{ 'overflow-y-auto': !indexConfig.leftBottomSwiper }">
     <component
@@ -79,27 +146,26 @@ onMounted(() => {
             <div class="dibu"></div>
             <div class="flex">
               <div class="info">
-                <span class="labels">设备ID:</span>
-                <span class="text-content zhuyao doudong wangguan"> {{ item.gatewayno }}</span>
+                <span class="labels">事件ID:</span>
+                <span class="text-content zhuyao doudong wangguan">{{ item.id }}</span>
               </div>
               <div class="info">
                 <span class="labels">时间:</span>
-                <span class="text-content" style="font-size: 12px"> {{ item.createTime }}</span>
+                <span class="text-content" style="font-size: 12px">{{ formatDate(new Date(item.CreatedAt), 'yyyy-MM-dd HH:mm:ss') }}</span>
               </div>
             </div>
 
             <span
               class="types doudong"
               :class="{
-                typeRed: item.onlineState == 0,
-                typeGreen: item.onlineState == 1,
+                typeRed: item.subEventType === 76,
+                typeGreen: item.subEventType === 75,
               }"
-              >{{ item.onlineState == 1 ? "上线" : "下线" }}</span
-            >
+            >{{ formatState(item.subEventType) }}</span>
 
             <div class="info addresswrap">
               <span class="labels">地址:</span>
-              <span class="text-content ciyao" style="font-size: 12px"> {{ addressHandle(item) }}</span>
+              <span class="text-content ciyao" style="font-size: 12px">{{ formalocation(item, null, item.ipAddress, i) }}</span>
             </div>
           </div>
         </li>

+ 1 - 1
src/views/index/left-top.vue

@@ -25,7 +25,7 @@ function getData(){
 }
 const startPolling = () => {
   getData();
-  setInterval(getData, 5000); // 每5秒轮询一次
+  setInterval(getData, 1000); // 每5秒轮询一次
 };
 onMounted(() => {
   startPolling();