Browse Source

动态图标,门禁记录管理

huangyan 7 months ago
parent
commit
ad7b260909

+ 0 - 2
index.html

@@ -28,8 +28,6 @@
   <script async src="https://vdata.baozhida.cn/3d1v/static/js/libs/loading/load.js" charset="utf-8"></script>
   <!-- 3D 1v -->
 </body>
-<script type="text/javascript" src="/public/jessibuca/jessibuca.js"></script>
-<script type="text/javascript" src="/src/H5player/bin/h5player.min.js"></script>
 <script type="text/javascript" src="/src/webrtc/webrtcstreamer.js"></script>
 <script type="text/javascript" src="/src/webrtc/adapter.min.js"></script>
 </html>

+ 11 - 0
src/api/modules/monitor.ts

@@ -0,0 +1,11 @@
+import { GET,POST } from "../api";
+
+// 定义登录URLs
+const Monitor = {
+    'monitor': '/monitor',
+};
+
+export const GetMonitor = (param: any = {}) => {
+    return POST(Monitor.monitor,param);
+};
+export { Monitor };

+ 11 - 0
src/api/modules/temperature.ts

@@ -0,0 +1,11 @@
+import { GET } from "../api";
+
+// 定义登录URLs
+const temperature = {
+    'temperature': '/temperature', 
+};
+
+export const Gettemperature = (param: any = {}) => {
+    return GET(temperature.temperature,param);
+};
+export { temperature };

+ 16 - 5
src/assets/css/main.scss

@@ -25,19 +25,19 @@ body {
 #iot3d {
   position: absolute;
   top: 3%;
-  left: 0;
+  left: 25%;
   transform: translate(0, 0);
   // border: 5px solid rgba(247, 0, 0, 0.5);
   margin-top: 5vh;
-  width: 100%;
-  height: 80vh;
+  width: 50%;
+  height: 55vh;
 }
 
 #iot3d>div,
 #iot3d>canvas {
   position: absolute;
   top: 0;
-  left: 0;
+  left: 50;
   width: 100% !important;
   height: 100% !important;
   // border: #059465 solid 5px;
@@ -94,7 +94,18 @@ html .el-message {
     color: var(--yh-text-color-primary);
   }
 }
-
+.el-table {
+  --el-table-border-color: transparent;
+  --el-table-border: none;
+  --el-table-text-color: #bdbdbe;
+  --el-table-header-text-color: #bdbdbe;
+  --el-table-row-hover-bg-color: transparent;
+  --el-table-current-row-bg-color: transparent;
+  --el-table-header-bg-color: transparent;
+  --el-table-bg-color: transparent;
+  --el-table-tr-bg-color: transparent;
+  --el-table-expanded-cell-bg-color: transparent;
+}
 .beautify-scroll-def {
   overflow-y: auto;
 

BIN
src/assets/img/aigei.gif


BIN
src/assets/img/bule.gif


BIN
src/assets/img/com.gif


BIN
src/assets/img/gee.gif


BIN
src/assets/img/gggg.gif


BIN
src/assets/img/red.gif


+ 1 - 1
src/config/UtilVar.ts

@@ -19,7 +19,7 @@ const runtimeType:any = {
     },
     //开发环境
     development: () => {
-        UtilVar.baseUrl= "http://localhost:8080/api"
+        UtilVar.baseUrl= "http://localhost:8181/api"
 
     },
     hash:()=>{

+ 1 - 1
src/views/index/archives.vue

@@ -1,7 +1,7 @@
 <template>
       <n-button strong secondary type="info" size="large" @click="$router.push('/')" class="back-home-btn">返回首页</n-button>
     <ItemWrap class="adduser-items" title="档案管理">
-        <iframe src="http://127.0.0.1:8082/docm-boot/index.html" id="mobsf"></iframe>
+        <iframe src="http://45.251.93.106:8082/index.html" id="mobsf"></iframe>
     </ItemWrap>
 </template>
  

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

@@ -22,8 +22,6 @@
       <ItemWrap class="contetn_center-bottom contetn_lr-item" title="视频监控">
         <!-- <CenterBottom /> -->
 <!--         <Monitor></Monitor>-->
-        <!-- <webrtc class="monitor" :streamurl="stream_url"></webrtc> -->
-        <!-- <webrtc class="monitor" style="width: 400px;height: 950px;" :streamurl="stream_url"></webrtc> -->
          <div class="monitor-container">
         <div class="monitor"  v-for="(stream, index) in stream_url">
           <webrtc :key="stream.id" :streamurl="stream.url" :videoId="'video-' + index"></webrtc>
@@ -171,18 +169,16 @@ import { id } from 'element-plus/es/locale';
 const shouldShowComponent = ref(true);
 
 let stream_url = ref([
-  {id:1,url:'rtsp://admin:jxzs12345@192.168.1.3:554/h264/ch1/main/av_stream'},
-  {id:2,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
-  {id:3,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
-  {id:4,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
-  {id:5,url:'rtsp://admin:jxzs12345@192.168.1.7: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.7:554/h264/ch1/main/av_stream'},
-  {id:8,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  { 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' },
 ]);
 
-
-
 onBeforeRouteLeave((to, from, next) => {
   shouldShowComponent.value = false;
   next();
@@ -273,7 +269,7 @@ onBeforeRouteLeave((to, from, next) => {
 .index-box{
   z-index: 1000000 !important;
 }
-.monitor{
+.monitor {
   margin-left: 10px;
   width: 50% !important;
   height: 100% !important;

+ 52 - 138
src/views/index/left-center.vue

@@ -1,21 +1,14 @@
 <script setup lang="ts">
-import { ref, reactive } from "vue";
+import { ref, reactive,onMounted } from "vue";
 import { graphic } from "echarts/core";
 import { countUserNum } from "@/api";
 import { ElMessage } from "element-plus"
 import { GetArchives } from "@/api/modules/External_interfaces";
+import { color } from "echarts";
 let colors = ["#0BFC7F", "#A0A0A0", "#F48C02", "#F4023C"];
 const option = ref({});
-const state = reactive({
-  lockNum: 0,
-  offlineNum: 0,
-  onlineNum: 0,
-  alarmNum: 0,
-  totalNum: 0,
-});
-
-let states = reactive({
-  qzCount: 0, //全宗数
+const states = reactive({
+  qzCount: 1000, //全宗数
   qsCount: 0,//卷数
   jsCount: 0,//件数
   dzdaCount: 0,//电子档案数据量
@@ -25,144 +18,65 @@ let states = reactive({
   queryCount: 0,//今年累计档案查询人次与查询件数
   fileCount: 0,//全宗卷文件数
 });
-const echartsGraphic = (colors: string[]) => {
-  return new graphic.LinearGradient(1, 0, 0, 0, [
-    { offset: 0, color: colors[0] },
-    { offset: 1, color: colors[1] },
-  ]);
-};
 function getData(){
   GetArchives().then(res => {
-    console.log('左上--设备总览', res);
     if (res.code === 200) {
-    states.qzCount = res.data.ckNum;
-    states.qsCount = res.data.ckNum;
-    states.jsCount = res.data.ckNum;
-    states.dzdaCount = res.data.ckNum;
-    states.yjCount = res.data.ckNum;
-    states.cqqsCount = res.data.ckNum;
-    states.cqjsCount = res.data.ckNum;
-    states.queryCount = res.data.ckNum;
-    states.fileCount = res.data.ckNum;
+      states.qzCount = 1000;
+      states.qsCount = res.data.qzCount;
+      states.jsCount = res.data.qzCount;
+      states.dzdaCount = res.data.qzCount;
+      states.yjCount = res.data.qzCount;
+      states.cqqsCount = res.data.qzCount;
+      states.cqjsCount = res.data.qzCount;
+      states.queryCount = res.data.qzCount;
+      states.fileCount = res.data.qzCount;
     }
-    
   })
 }
-getData()
 
 const setOption = () => {
-  option.value = {
-    title: {
-      top: "center",
-      left: "center",
-      text: [`{value|${states.qzCount}}`, "{name|总数}"].join("\n"),
-      textStyle: {
-        rich: {
-          value: {
-            color: "#ffffff",
-            fontSize: 24,
-            fontWeight: "bold",
-            lineHeight: 20,
-            padding: [4, 0, 4, 0]
-          },
-          name: {
-            color: "#ffffff",
-            lineHeight: 20,
-          },
-        },
-      },
-    },
-    tooltip: {
-      trigger: "item",
-      backgroundColor: "rgba(0,0,0,.6)",
-      borderColor: "rgba(147, 235, 248, .8)",
-      textStyle: {
-        color: "#FFF",
-      },
-    },
-    series: [
-      {
-        name: "馆藏统计",
-        type: "pie",
-        radius: ["30%", "70%"],
-        // avoidLabelOverlap: false,
-        itemStyle: {
-          borderRadius: 6,
-          borderColor: "rgba(255,255,255,0)",
-          borderWidth: 2,
-        },
-        color: colors,
-        label: {
-          show: true,
-          // formatter: "   {b|{b}}   \n   {c|{c}个}   {per|{d}%}  ",
-          formatter: "   {b|{b}}   \n   {c|{c}个}",
-          position: "inside",
-          rich: {
-            b: {
-              color: "#fff",
-              fontSize: 16,
-              lineHeight: 26,
-            },
-            c: {
-              color: "#31ABE3",
-              fontSize: 16,
-            },
-            per: {
-              color: "#31ABE3",
-              fontSize: 6,
-            },
-          },
+  option.value =  {
+  tooltip: {
+    trigger: 'item'
+  },
+  legend: {
+    top: '5%',
+    left: 'center'
+  },
+  series: [
+    {
+      name: '馆藏统计',
+      type: 'pie',
+      radius: ['40%', '80%'],
+      center: ['50%', '80%'],
+      // adjust the start and end angle
+      startAngle: 180,
+      endAngle: 360,
+      label: {
+        show: true,
+        color: '#FFFFFF',
+        formatter: (params: any) => {
+          return `${params.name}:${params.value}`;
         },
-        emphasis: {
-          show: false,
-        },
-        legend: {
-          show: true,
-        },
-        tooltip: { show: true },
-
-        // labelLine: {
-        //   show: true,
-        //   length: 20, // 第一段线 长度
-        //   length2: 36, // 第二段线 长度
-        //   smooth: 0.2,
-        //   lineStyle: {},
-        // },
-        data: [
-          {
-            value: states.qsCount,
-            name: "卷数",
-            itemStyle: {
-              color: echartsGraphic(["#0BFC7F", "#A3FDE0"]),
-            },
-          },
-          {
-            value: states.jsCount,
-            name: "件数",
-            itemStyle: {
-              color: echartsGraphic(["#A0A0A0", "#DBDFDD"]),
-            },
-          },
-          {
-            value: states.dzdaCount,
-            name: "电子档案数据量",
-            itemStyle: {
-              color: echartsGraphic(["#F48C02", "#FDDB7D"]),
-            },
-          },
-          {
-            value: states.yjCount,
-            name: "永久卷数",
-            itemStyle: {
-              color: echartsGraphic(["#F4023C", "#FB6CB7"]),
-            },
-          },
-        ],
       },
-    ],
-  };
+      data: [
+        { value: states.qzCount, name: '卷数' },
+        { value: 735, name: '件数' },
+        { value: 580, name: '电子档案数据量' },
+        { value: 484, name: '永久卷数' },
+      ]
+    }
+  ]
 };
-setOption();
+};
+const startPolling = () => {
+  getData();
+  setInterval(getData, 5000); // 每5秒轮询一次
+};
+onMounted(() => {
+  startPolling();
+  setOption();
+});
 </script>
 
 <template>

+ 20 - 28
src/views/index/left-top.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { reactive, ref } from "vue";
+import { reactive, ref,onMounted } from "vue";
 import { countDeviceNum } from "@/api";
 import CountUp from "@/components/count-up";
 import {ElMessage} from "element-plus"
@@ -12,27 +12,8 @@ const state = reactive({
   onlineNum: 0,
   totalNum: 0,
 });
-
-
-// const getData = () => {
-//   countDeviceNum().then((res) => {
-//     console.log("左上--设备总览",res);
-//     if (res.success) {
-//       state.alarmNum = res.data.alarmNum;
-//       state.offlineNum = res.data.offlineNum;
-//       state.onlineNum = res.data.onlineNum;
-//       state.totalNum = res.data.totalNum;
-//     }else{
-//       ElMessage.error(res.msg)
-//     }
-//   }).catch(err=>{
-//     ElMessage.error(err)
-//   });;
-// };
-// getData();
 function getData(){
   GetArchives().then(res => {
-    console.log('左上--设备总览', res);
     if (res.code === 200) {
       state.alarmNum = res.data.ckNum;
       state.offlineNum = res.data.ckNum;
@@ -42,9 +23,13 @@ function getData(){
     
   })
 }
-getData()
-
-
+const startPolling = () => {
+  getData();
+  setInterval(getData, 5000); // 每5秒轮询一次
+};
+onMounted(() => {
+  startPolling();
+});
 </script>
 
 <template>
@@ -97,7 +82,7 @@ getData()
       height: 100px;
       text-align: center;
       line-height: 100px;
-      font-size: 18px;
+      font-size: 25px;
       margin: 50px auto 30px;
       background-size: cover;
       background-position: center center;
@@ -119,25 +104,32 @@ getData()
 
     .allnum {
       &::before {
-        background-image: url("@/assets/img/left_top_lan.png");
+        background: url("@/assets/img/bule.gif");
+        background-size: 100% 100%;
       }
     }
 
     .online {
       &::before {
-        background-image: url("@/assets/img/left_top_lv.png");
+        //background-image: url("@/assets/img/left_top_lv.png");
+        background: url("@/assets/img/gee.gif");
+        background-size: 100% 100%;
       }
     }
 
     .offline {
       &::before {
-        background-image: url("@/assets/img/left_top_huang.png");
+        //background-image: url("@/assets/img/left_top_huang.png");
+        background: url("@/assets/img/gggg.gif");
+        background-size: 100% 100%;
       }
     }
     
     .laramnum {
       &::before {
-        background-image: url("@/assets/img/left_top_hong.png");
+        //background-image: url("@/assets/img/left_top_hong.png");
+        background: url("@/assets/img/red.gif");
+        background-size: 100% 100%;
       }
     }
   }

+ 329 - 261
src/views/index/message-center.vue

@@ -1,303 +1,333 @@
 <template>
-    <n-button strong secondary type="info" size="large" @click="$router.push('/')" class="back-home-btn">返回首页</n-button>
-    <ItemWrap class="contetn_left-bottom contetn_lr-item" title="消息中心">
-        <div class="demo-datetime-picker">
-            <div class="block" v-if="currentView === 'alarm'">
-                <el-date-picker class="date-picker" v-model="datatime" type="datetimerange" range-separator="至"
-                    start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD HH:mm:ss"
-                    date-format="YYYY/MM/DD ddd" time-format="A hh:mm:ss" />
-            </div>
+  <n-button strong secondary type="info" size="large" @click="$router.push('/')" class="back-home-btn">返回首页
+  </n-button>
+  <ItemWrap class="contetn_left-bottom contetn_lr-item" title="消息中心">
+    <div class="demo-datetime-picker">
+      <div class="block">
+        <el-date-picker class="date-picker" v-model="datatime" type="datetimerange" range-separator="至"
+                        start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD HH:mm:ss"
+                        date-format="YYYY/MM/DD ddd" time-format="A hh:mm:ss"/>
+      </div>
+      <n-button strong secondary type="info" class="btn-search"
+                @click="getStockRecord">
+        搜索
+      </n-button>
+    </div>
+    <div class="btngroup">
+      <el-button type="primary" class="btntype" @click="switchView('alarm')">报警信息
 
-            <!-- <n-input class="input-search" placeholder="请输入内容" v-model="input" :clearable="true" /> -->
-            <n-button strong secondary type="info" v-if="currentView === 'alarm'" class="btn-search"
-                @click="showAddUser">
-                搜索
-            </n-button>
+      </el-button>
+      <el-button type="primary" class="btntype" @click="switchView('stock')">门禁记录
 
-        </div>
-        <div class="btngroup">
-            <el-button type="primary" class="btntype" @click="switchView('alarm')">报警信息
-                
-            </el-button>
-            <el-button type="primary" class="btntype" @click="switchView('stock')">库存情况
-                
-            </el-button>
-        </div>
-        <div class="user_skills" style="margin-top:20px;">
-            <n-table striped class="eltables" :bordered="true" v-if="currentView === 'alarm'">
-                <thead>
-                    <tr>
-                        <th>报警类型</th>
-                        <th>报警详情</th>
-                        <th>设备地址</th>
-                        <th>报警时间</th>
-                        <th>通知状态</th>
-                    </tr>
-                </thead>
-                <tbody>
-                    <tr v-for="(item, index) in tableData">
-                        <td>{{ item.warntype }}</td>
-                        <td>{{ item.detail }}</td>
-                        <td>{{ item.address }}</td>
-                        <td>{{ item.date }}</td>
-                        <td>{{ item.state }}</td>
-                    </tr>
-                </tbody>
-            </n-table>
-            <div v-if="currentView === 'stock'" style="display: flex; justify-content: center; width: 100%;">
-                <div ref="chartRef" style="width: 400px; height: 400px;"></div>
-            </div>
-            <!-- <el-table  :data="tableDatas" class="eltables">
-                <el-table-column prop="product" label="产品名称" />
-                <el-table-column prop="quantity" label="库存" />
-                <el-table-column prop="location" label="仓库" />
-                <el-table-column prop="lastUpdate" label="时间" />
-            </el-table> -->
-            <el-pagination class="pagination" v-if="currentView === 'alarm'" background layout="prev, pager, next"
-                :total="totalItems" :page-size="pageSize" :current-page="currentPage"
-                @current-change="handleCurrentChange" />
-        </div>
-    </ItemWrap>
+      </el-button>
+    </div>
+    <div class="user_skills" style="margin-top:20px;">
+      <el-table :data="tableData" height="650" style="width: 100%; margin: auto;" class="eltables" :bordered="true"
+                v-if="currentView === 'alarm'">
+        <el-table-column prop="date" label="创建时间"/>
+        <el-table-column prop="warntype" label="账号"/>
+        <el-table-column prop="state" label="状态" :formatter="formatState"/>
+        <el-table-column label="操作">
+          <template #default="{ row }">
+            <n-button strong secondary type="info" size="large" @click="showEdit(row)" style="margin-right: 5px;"
+                      class="edtbtn">编辑
+            </n-button>
+            <n-button strong secondary type="success" class="edtbtn" size="large" @click="updateUser(row.id, 1)">启用
+            </n-button>
+            <n-button strong secondary type="warning" class="edtbtn" size="large" @click="updateUser(row.id, 2)">禁用
+            </n-button>
+            <n-button strong secondary type="error" class="edtbtn" size="large" @click="deleteUser(row.id)">删除
+            </n-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div v-if="currentView === 'stock'" style="display: flex; justify-content: center; width: 100%;">
+        <!--                <div ref="chartRef" style="width: 400px; height: 400px;"></div>-->
+        <el-table :data="monitor" height="650" style="width: 100%; margin: auto;" class="eltables" :bordered="true">
+          <el-table-column label="序号" width="100">
+            <template #default="{ $index }">
+              {{ (userform.page - 1) * userform.size + $index + 1 }}
+            </template>
+          </el-table-column>
+          <el-table-column prop="CreatedAt" label="验证时间"/>
+          <el-table-column prop="ipAddress" label="位置" :formatter="formalocation"/>
+          <el-table-column prop="majorEventType" label="验证类型"/>
+          <el-table-column prop="subEventType" label="是否通过" :formatter="formatState"/>
+          <el-table-column label="预览">
+            <template #default="{ row }">
+              <n-button strong secondary type="info" @click="showImages(row.faceImagePath)">预览图片</n-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+      <el-dialog v-model="dialogVisible"  title="图片预览" width="50%">
+        <ItemWrap title="图片预览" style="font-size: 20px"><el-image :src="currentImage" fit="contain"></el-image></ItemWrap>
+      </el-dialog>
+      <el-pagination
+          class="pagination"
+          background
+          layout="prev, pager, next"
+          :total="page_count"
+          :page-size="userform.size"
+          :current-page="userform.page"
+          @size-change="handleSizeChange"
+          @current-change="handlePageChange"
+          v-if="currentView === 'stock'"
+      />
+    </div>
+  </ItemWrap>
 </template>
 <script setup lang="ts">
-import { ref, reactive, watchEffect, onMounted,onUnmounted } from "vue";
-import CapsuleChart from "@/components/datav/capsule-chart";
-import { ranking } from "@/api";
-import { ElMessage } from "element-plus";
-import Adduser from "./adduser.vue";
-import { NInput, NTable } from "naive-ui";
+import {onMounted, onUnmounted, reactive, ref, watchEffect} from "vue";
 import * as echarts from "echarts";
+import ItemWrap from "@/components/item-wrap";
+import {GetMonitor} from "api/modules/monitor";
+let page_count = ref(0);
+const isLoading = ref(false);
 const chartRef = ref<HTMLDivElement | null>(null);
+const datatime = ref('')
+const isAddUserVisible = ref(false);
 let chartInstance: echarts.ECharts | null = null;
-
+const userform = reactive({
+  "page": 1,
+  "size": 10,
+  "startTime": "",
+  "endTime": ""
+});
 const tableData = [
-    {
-        warntype: '断电报警',
-        date: '2016-05-03',
-        detail: '设备断电报警',
-        address: 'No. 189, Grove St, Los Angeles',
-        state: 'No',
-    },
-    {
-        warntype: '断电报警',
-        date: '2016-05-03',
-        detail: '设备断电报警',
-        address: 'No. 189, Grove St, Los Angeles',
-        state: 'No',
-    },
-    {
-        warntype: '断电报警',
-        date: '2016-05-03',
-        detail: '设备断电报警',
-        address: 'No. 189, Grove St, Los Angeles',
-        state: 'No',
-    },
-    {
-        warntype: '断电报警',
-        date: '2016-05-03',
-        detail: '设备断电报警',
-        address: 'No. 189, Grove St, Los Angeles',
-        state: 'No',
-    },
+  {
+    warntype: '断电报警',
+    date: '2016-05-03',
+    detail: '设备断电报警',
+    address: 'No. 189, Grove St, Los Angeles',
+    state: 'No',
+  },
+  {
+    warntype: '断电报警',
+    date: '2016-05-03',
+    detail: '设备断电报警',
+    address: 'No. 189, Grove St, Los Angeles',
+    state: 'No',
+  },
+  {
+    warntype: '断电报警',
+    date: '2016-05-03',
+    detail: '设备断电报警',
+    address: 'No. 189, Grove St, Los Angeles',
+    state: 'No',
+  },
+  {
+    warntype: '断电报警',
+    date: '2016-05-03',
+    detail: '设备断电报警',
+    address: 'No. 189, Grove St, Los Angeles',
+    state: 'No',
+  },
 ];
+let monitor = ref([{
+  id: '',
+  faceImagePath: '',
+  majorEventType: '',
+  subEventType: '',
+  CreatedAt: '',
+  ipAddress:''
+}])
+
+function formatState(row, column, cellValue, index) {
+  switch (cellValue) {
+    case 75:
+      return "验证通过";
+    case 76:
+      return "验证失败";
+    default:
+      return "未知";
+  }
+}
+function formalocation(row, column, cellValue, index) {
+  switch (cellValue) {
+    case '192.168.1.103':
+      return "二楼门禁";
+    case '192.168.1.104':
+      return "四楼门禁";
+    default:
+      return "未知";
+  }
+}
+// 弹窗显示状态
+const dialogVisible = ref(false);
+const currentImage = ref('');
+const showImages = (imagePaths) => {
+  if (imagePaths.length > 0) {
+    currentImage.value = "http://localhost:8181"+imagePaths;
+    dialogVisible.value = true;
+  }
+};
+
+function formatDate(date, format) {
+  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) => map[match]);
+}
 
+//获取门禁记录
+function getStockRecord() {
+  isLoading.value = true;
+  if( datatime.value.length>=2){
+    userform.startTime = formatDate(datatime.value[0], 'yyyy-MM-dd HH:mm:ss');
+    userform.endTime = formatDate(datatime.value[1], 'yyyy-MM-dd HH:mm:ss');
+  }
+    GetMonitor(userform).then(res => {
+      if (res.code === 200) {
+        console.log(res.data.result)
+        monitor.value=res.data.result
+        page_count.value = res.data.total;
+        isLoading.value = false;
+      }
+    })
+}
+const handlePageChange = (newPage) => {
+  userform.page = newPage;
+  getStockRecord();
+};
 
+const handleSizeChange = (size) => {
+  userform.size = size;
+  getStockRecord();
+};
 // 当前视图标识
 const currentView = ref('alarm');
 
 // 切换视图
 const switchView = (view: string) => {
-    currentView.value = view;
-    
-    if (view === 'stock') {
-        if (chartInstance) {
-            // 更新图表配置
-            chartInstance.setOption(options);
-            chartInstance.resize(); // 确保图表尺寸适应新的视图
-        } else {
-            // 创建新的图表实例
-            chartInstance = echarts.init(chartRef.value);
-            chartInstance.setOption(options);
-        }
-    } else {
-        // 如果离开库存情况视图,销毁图表实例
-        if (chartInstance) {
-            chartInstance.dispose();
-            chartInstance = null;
-        }
-    }
+  currentView.value = view;
+  if (view === 'stock') {
+  }
 };
 // 初始化数据
 switchView("alarm");
 
-const datatime = ref('')
-const input = ref('')
-const isAddUserVisible = ref(false);
-const showAddUser = () => {
-    isAddUserVisible.value = true;
-};
-// 分页相关状态
-const pageSize = ref(10); // 每页显示的条目数
-const currentPage = ref(1); // 当前页码
-const totalItems = ref(tableData.length); // 总条目数
-
-// 根据当前页码和每页大小计算显示的数据
-// const displayedTableData = computed(() => {
-//   const start = (currentPage.value - 1) * pageSize.value;
-//   const end = start + pageSize.value;
-//   return tableData.slice(start, end);
-// });
-
-// 当前页码改变时触发的方法
-const handleCurrentChange = (val: number) => {
-    currentPage.value = val;
-};
-
-
-const options = reactive({
-    tooltip: {},
-    legend: {
-        top: 'bottom'
-    },
-    series: [
-        {
-            name: '访问来源',
-            type: 'pie',
-            radius: '100%',
-            roseType: 'area',
-            center: ['50%', '50%'],
-            itemStyle: {
-                borderRadius: 8
-            },
-            data: [
-                { value: 40, name: 'rose 1' },
-                { value: 38, name: 'rose 2' },
-                { value: 32, name: 'rose 3' },
-                { value: 30, name: 'rose 4' },
-                { value: 28, name: 'rose 5' },
-                { value: 26, name: 'rose 6' },
-                { value: 22, name: 'rose 7' },
-                { value: 18, name: 'rose 8' }
-            ],
-            emphasis: {
-                itemStyle: {
-                    shadowBlur: 10,
-                    shadowOffsetX: 0,
-                    shadowColor: 'rgba(0, 0, 0, 0.5)'
-                }
-            }
-        }
-    ]
-});
 
-const initChart = () => {
-    if (chartRef.value && !chartInstance) {
-        chartInstance = echarts.init(chartRef.value);
-        chartInstance.setOption(options);
-    } else if (chartInstance) {
-        chartInstance.setOption(options);
-    }
+const showAddUser = () => {
+  isAddUserVisible.value = true;
 };
 
-watchEffect(() => {
-    initChart();
-});
-
 onMounted(() => {
-    window.addEventListener('resize', initChart);
-    return () => {
-        window.removeEventListener('resize', initChart);
-    };
-});
-onUnmounted(() => {
-    if (chartInstance) {
-        chartInstance.dispose();
-        chartInstance = null;
-    }
+  getStockRecord();
 });
 </script>
 
 <style scoped>
 .contetn_lr-item {
-    font-size: 30px;
-    margin-top: 80px;
-    height: 800px;
+  font-size: 30px;
+  margin-top: 80px;
+  height: 800px;
 }
 
 .btn-search,
 .back-home-btn {
-    /* background-color: transparent; */
-    position: absolute;
-    margin-top: 30px;
-    top: 10px;
-    left: 10px;
+  /* background-color: transparent; */
+  position: absolute;
+  margin-top: 30px;
+  top: 10px;
+  left: 10px;
 }
 
 .btn-search {
-    margin-top: 37px;
-    margin-left: 25%;
-    height: 45px;
+  margin-top: 37px;
+  margin-left: 25%;
+  height: 45px;
 }
 
 .input-search {
-    background-color: transparent !important;
-    border: #006ff0;
-    width: 200px;
-    height: 50px;
-    font-size: 20px;
-    margin-top: 10px;
-    top: -60px;
-    left: 450px;
-    padding: auto;
-    color: #006ff0;
+  background-color: transparent !important;
+  border: #006ff0;
+  width: 200px;
+  height: 50px;
+  font-size: 20px;
+  margin-top: 10px;
+  top: -60px;
+  left: 450px;
+  padding: auto;
+  color: #006ff0;
 }
 
 .btntype {
-    background-color: transparent;
-    align-items: center;
-    justify-content: center;
-    height: 50px;
-    font-size: large
+  background-color: transparent;
+  align-items: center;
+  justify-content: center;
+  height: 50px;
+  font-size: large
 }
 
 .btngroup {
-    margin-top: 10px;
-    display: flex;
-    justify-content: center;
+  margin-top: 10px;
+  display: flex;
+  justify-content: center;
 }
 
 .user_skills {
-    width: 100%;
-    text-align: center;
-    font-size: larger;
+  width: 100%;
+  text-align: center;
+  font-size: larger;
 }
 
 ::v-deep .pagination {
-    display: flex;
-    justify-content: right;
-    align-items: center;
-    margin-right: 15px;
-    margin-top: 280px;
+  display: flex;
+  justify-content: right;
+  align-items: center;
+  margin-right: 15px;
+  margin-top: -10px;
+}
+
+::v-deep .el-dialog::before {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  z-index: -1;
+  /* 确保伪元素在内容之下 */
+  background-color: inherit;
+  /* 继承父元素的背景色 */
+  backdrop-filter: blur(5px);
+  -webkit-backdrop-filter: blur(10px);
+}
+::v-deep .el-dialog__body {
+  display: flex;
+  justify-content: center;
+  align-items: center;
 }
 
+::v-deep .el-dialog {
+  position: relative;
+  /* 确保伪元素定位正确 */
+  background-color: rgba(255, 255, 255, 0.1);
+}
 /* 使分页器中的按钮背景透明 */
 ::v-deep .el-pagination button,
 ::v-deep .el-pagination .btn-quicknext,
 ::v-deep .el-pagination .btn-next,
 ::v-deep .el-pagination .btn-prev,
 ::v-deep .el-pagination .btn-quickprev {
-    height: 40px;
-    width: 40px;
-    font-size: 20px;
-    background-color: rgba(17, 0, 255, 0.3) !important;
-    /* 半透明灰色 */
-    border-color: rgba(128, 128, 128, 0.3) !important;
+  height: 40px;
+  width: 40px;
+  font-size: 20px;
+  background-color: rgba(17, 0, 255, 0.3) !important;
+  /* 半透明灰色 */
+  border-color: rgba(128, 128, 128, 0.3) !important;
 }
 
 /* 使分页器中的数字和链接透明 */
 ::v-deep .el-pagination .el-pager li {
-    background-color: transparent !important;
-    border-color: transparent !important;
+  background-color: transparent !important;
+  border-color: transparent !important;
 }
 
 /* 当鼠标悬停或激活时,保持背景透明 */
@@ -305,46 +335,84 @@ onUnmounted(() => {
 ::v-deep .el-pagination button:focus,
 ::v-deep .el-pagination .el-pager li:hover,
 ::v-deep .el-pagination .el-pager li.is-active {
-    height: 40px;
-    width: 40px;
-    font-size: 16px;
-    background-color: rgba(104, 3, 255, 0.5) !important;
-    /* 加深的半透明灰色 */
+  height: 40px;
+  width: 40px;
+  font-size: 16px;
+  background-color: rgba(104, 3, 255, 0.5) !important;
+  /* 加深的半透明灰色 */
 }
 
 ::v-deep .date-picker {
-    background-color: transparent;
-    height: 50px;
-    font-size: 30px;
-    left: 20px;
-    border-width: 1px;
-    border-style: solid;
-    border-color: blue;
-    border-radius: 10px;
+  background-color: transparent;
+  height: 50px;
+  font-size: 30px;
+  left: 20px;
+  border-width: 1px;
+  border-style: solid;
+  border-color: blue;
+  border-radius: 10px;
 }
 
 /* naive */
 .eltables {
-    background-color: transparent !important;
-    font-size: 20px;
-    text-align: center;
-    border: none;
+  background-color: transparent !important;
+  font-size: 20px;
+  text-align: center;
+  border: none;
 }
 
 .eltables th {
-    background-color: transparent !important;
-    color: #006ff0;
-    border: none;
+  background-color: transparent !important;
+  color: #006ff0;
+  border: none;
 }
 
 .eltables td {
-    background-color: transparent !important;
-    color: #009ffb;
-    border: none;
+  background-color: transparent !important;
+  color: #009ffb;
+  border: none;
 }
 
 .eltables td:hover {
-    background-color: rgba(0, 0, 0, 0.1);
-    /* 半透明的灰色背景 */
+  background-color: rgba(0, 0, 0, 0.1);
+  /* 半透明的灰色背景 */
+}
+
+.el-table {
+  --el-table-border-color: transparent;
+  --el-table-border: none;
+  --el-table-text-color: #bdbdbe;
+  --el-table-header-text-color: #bdbdbe;
+  --el-table-row-hover-bg-color: transparent;
+  --el-table-current-row-bg-color: transparent;
+  --el-table-header-bg-color: transparent;
+  --el-table-bg-color: transparent;
+  --el-table-tr-bg-color: transparent;
+  --el-table-expanded-cell-bg-color: transparent;
+}
+
+.eltables {
+  text-align: center;
+  border: none;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+}
+::v-deep .el-table th {
+  background-color: transparent !important;
+  color: #006ff0;
+  margin: auto;
+  justify-content: center;
+  align-items: center;
+  text-align: center;
+}
+
+::v-deep .el-table td {
+  background-color: transparent !important;
+  color: #009ffb;
+  margin: auto;
+  justify-content: center;
+  align-items: center;
+  text-align: center;
 }
 </style>

+ 1 - 1
src/views/index/right-center.vue

@@ -2,7 +2,7 @@
   <ul class="user_Overview flex">
     <li class="user_Overview-item" style="color: #f0e728">
       <img src="@/assets/img/co2.png" class="user_Overview_image">
-      <p>20</p>
+      <p>5</p>
     </li>
     <li class="user_Overview-item" style="color: #c11f6f">
       <img src="@/assets/img/hcho.png" style="width: 90%;margin-top: 60px;" class="user_Overview_image">

+ 27 - 38
src/views/index/right-top.vue

@@ -3,40 +3,24 @@ import { ref, onMounted } from "vue";
 import { alarmNum } from "@/api";
 import { graphic } from "echarts/core";
 import { ElMessage } from "element-plus";
-
+import { Gettemperature } from "@/api/modules/temperature";
 const option = ref({});
-const getData = () => {
-  // alarmNum()
-  //   .then((res) => {
-  //     console.log("右上--报警次数 ", res);
-  //     if (res.success) {
-  //       setOption(res.data.dateList, res.data.numList, res.data.numList2);
-  //     } else {
-  //       ElMessage({
-  //         message: res.msg,
-  //         type: "warning",
-  //       });
-  //     }
-  //   })
-  //   .catch((err) => {
-  //     ElMessage.error(err);
-  //   });
-  const { xData, yData, yData2 } = generateFakeData();
-  setOption(xData, yData, yData2);
-};
-const generateFakeData = () => {
-  const xData = [];
-  const yData = [];
-  const yData2 = [];
-
-  for (let i = 0; i < 10; i++) {
-    xData.push(`日期${i + 1}`);
-    yData.push(Math.floor(Math.random() * 100));
-    yData2.push(Math.floor(Math.random() * 100));
-  }
+function getTemperature(){
+  Gettemperature().then(res=>{
+    if (res.code === 200) {
+      const xData = [];
+      const yData = [];
+      const yData2 = [];
+      for (let i = 0; i < res.data.length; i++) {
+        xData.push(res.data[i].upload_time); //日期
+        yData.push(res.data[i].temperature); //温度
+        yData2.push(res.data[i].humidity);//湿度
+      }
+      setOption(xData, yData, yData2);
+    }
+  })
+}
 
-  return { xData, yData, yData2 };
-};
 const setOption = async (xData: any[], yData: any[], yData2: any[]) => {
   option.value = {
     xAxis: {
@@ -50,7 +34,7 @@ const setOption = async (xData: any[], yData: any[], yData2: any[]) => {
         },
       },
       axisLine: {
-        // show:false,
+        show:false,
         lineStyle: {
           color: "rgba(31,99,163,.1)",
         },
@@ -102,7 +86,7 @@ const setOption = async (xData: any[], yData: any[], yData2: any[]) => {
         type: "line",
         smooth: true,
         symbol: "none", //去除点
-        name: "报警1次数",
+        name: "温度",
         color: "rgba(252,144,16,.7)",
         areaStyle: {
           //右,下,左,上
@@ -143,7 +127,7 @@ const setOption = async (xData: any[], yData: any[], yData2: any[]) => {
                 padding: [7, 14],
                 borderWidth: 0.5,
                 borderColor: "rgba(252,144,16,.5)",
-                formatter: "报警1:{c}",
+                formatter: "温度:{c}·C",
               },
             },
             {
@@ -169,7 +153,7 @@ const setOption = async (xData: any[], yData: any[], yData2: any[]) => {
         type: "line",
         smooth: true,
         symbol: "none", //去除点
-        name: "报警2次数",
+        name: "湿度",
         color: "rgba(9,202,243,.7)",
         areaStyle: {
           //右,下,左,上
@@ -210,7 +194,7 @@ const setOption = async (xData: any[], yData: any[], yData2: any[]) => {
                 borderRadius: 6,
                 borderColor: "rgba(9,202,243,.5)",
                 padding: [7, 14],
-                formatter: "报警2:{c}",
+                formatter: "湿度:{c}%",
                 borderWidth: 0.5,
               },
             },
@@ -235,8 +219,13 @@ const setOption = async (xData: any[], yData: any[], yData2: any[]) => {
     ],
   };
 };
+const startPolling = () => {
+  getTemperature();
+  setInterval(getTemperature, 5000); // 每5秒轮询一次
+};
+
 onMounted(() => {
-  getData();
+  startPolling();
 });
 </script>
 

+ 37 - 18
src/views/index/webH5.vue

@@ -5,10 +5,10 @@
   <n-button strong secondary type="info" size="large" @click="changeLayout(3)" class="btn">3x3</n-button>
   <ItemWrap class="contetn_lr-item" title="实时监控">
     <div class="grid-container">
-
       <div class="grid" :style="{ gridTemplateColumns: `repeat(${cols}, 1fr)` }">
-        <div v-for="n in cols * cols" :key="n"  class="cell">
-          <webrtc :streamurl="stream_url" ></webrtc>
+        <div v-for="(item, index) in stream_url.slice(0, cols * cols)" :key="index" class="cell">
+          <webrtc :key="item.id" :videoId="'video-' + index" :streamurl="item.url" class="video"></webrtc>
+<!--          <webrtc></webrtc>-->
         </div>
       </div>
     </div>
@@ -17,20 +17,31 @@
 
 <script lang="ts" setup>
 import { ref, onMounted } from 'vue';
-import TestWebH5 from './monitor.vue';
 import ItemWrap from '@/components/item-wrap/item-wrap.vue';
+import webrtc from './webrtc.vue';
 
 const cols = ref(3); // 初始为3列
+// 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: 9, url: 'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream' },
+// ]);
 let stream_url = ref([
-  {id:1,url:'rtsp://admin:jxzs12345@192.168.1.3:554/h264/ch1/main/av_stream'},
-  {id:2,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
-  {id:3,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
-  {id:4,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
-  {id:5,url:'rtsp://admin:jxzs12345@192.168.1.7: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.7:554/h264/ch1/main/av_stream'},
-  {id:8,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
-  {id:9,url:'rtsp://admin:jxzs12345@192.168.1.7:554/h264/ch1/main/av_stream'},
+  { id: 1, url: 'http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4' },
+  { id: 2, url: 'http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4' },
+  { id: 3, url: 'http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4' },
+  { id: 4, url: 'http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4' },
+  { id: 5, url: 'http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4' },
+  { id: 6, url: 'http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4' },
+  { id: 7, url: 'http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4' },
+  { id: 8, url: 'http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4' },
+  { id: 9, url: 'http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4' },
 ]);
 const changeLayout = (newCols: number) => {
   cols.value = newCols;
@@ -42,7 +53,6 @@ const changeLayout = (newCols: number) => {
   display: flex;
   flex-direction: column;
   align-items: center;
-  /* 设置全屏 */
   position: absolute;
   top: 0;
   left: 0;
@@ -64,19 +74,28 @@ const changeLayout = (newCols: number) => {
   font-size: 25px;
   height: 900px;
 }
-.btn{
+
+.btn {
   align-items: center;
   /* display: flex; */
   justify-content: center;
   margin-left: 10px;
 }
+
 .cell {
   /* 移除固定宽度 */
-  width: auto;
-  height: 100%;
+  width: 100%; /* 适应网格单元格宽度 */
+  /* 设置最大高度,避免撑大 */
+  max-height: 100%; /* 适应网格单元格高度 */
+  overflow: hidden; /* 隐藏超出部分 */
+  display: flex; /* 使用Flexbox布局 */
+  justify-content: center; /* 居中对齐 */
+  align-items: center; /* 居中对齐 */
   /* 单元格高度自适应 */
-  padding: 10px;
+  /* padding: 10px; */
   text-align: center;
   border: 1px solid #fff700;
 }
+
+
 </style>

+ 8 - 10
src/views/index/webrtc.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <video :id="videoId" autoplay></video>
+    <video :id="videoId" controls autoplay></video>
   </div>
 </template>
 
@@ -16,14 +16,6 @@ export default {
       type: String,
       default: 'video'
     },
-    width: {
-      type: Number,
-      default: 900
-    },
-    height: {
-      type: Number,
-      default: 1200
-    }
   },
   data() {
     return {
@@ -32,7 +24,6 @@ export default {
   },
   mounted() {
     this.webRtcServer = new WebRtcStreamer(this.videoId, location.protocol + '//127.0.0.1:8000')
-    console.log("this.streamurl in mounted:======================================", this.streamurl); // 打印组件中的值
     this.webRtcServer.connect(this.streamurl)
     const videoElement = document.getElementById(this.videoId);
     if (videoElement) {
@@ -52,3 +43,10 @@ export default {
   }
 }
 </script>
+<style scoped>
+video {
+  width: 100%;
+  height: 100%;
+  object-fit: cover; /* 使视频填充整个容器,保持原始宽高比 */
+}
+</style>