Compare commits

...

4 Commits

  1. 7
      public/dahua/demo.html
  2. 2
      public/dahua/lib/WSPlayer/player.css
  3. BIN
      src/assets/font/大屏标题.OTF
  4. BIN
      src/assets/images/bigbj.png
  5. BIN
      src/assets/images/changtitle.png
  6. BIN
      src/assets/images/databj.png
  7. BIN
      src/assets/images/datacontentbj.png
  8. BIN
      src/assets/images/datatitle.png
  9. BIN
      src/assets/images/datatopbj.png
  10. BIN
      src/assets/images/menu.png
  11. BIN
      src/assets/images/menutwo.png
  12. BIN
      src/assets/images/videoitembj.png
  13. BIN
      src/assets/images/videoitembjtwo.png
  14. 7
      src/assets/styles/index.scss
  15. 3
      src/components/texttooltip/index.vue
  16. 2
      src/layout/components/AppMain.vue
  17. 2
      src/main.js
  18. 1
      src/permission.js
  19. 1
      src/views/constructionScheduling/progress-monitoring/index.vue
  20. 369
      src/views/large-screen/index.vue
  21. 6
      src/views/large-screen/options.js
  22. 105
      src/views/large-screen/video.vue

@ -18,7 +18,7 @@
} }
.container { .container {
display: flex; display: flex;
padding: 0 10px !important; padding: 0 0px !important;
margin: 0!important; margin: 0!important;
max-width: none; max-width: none;
} }
@ -75,7 +75,7 @@
</div> </div>
</div> </div>
<!-- 中间内容部分 --> <!-- 中间内容部分 -->
<div class="container"> <div class="container" id="container">
<div class="real-container"> <div class="real-container">
<span id="real-title">实时预览:</span> <span id="real-title">实时预览:</span>
<div id="ws-real-player" style="height: 500px; margin-bottom: 20px;"></div> <div id="ws-real-player" style="height: 500px; margin-bottom: 20px;"></div>
@ -110,6 +110,9 @@
document.getElementById('real-btn-box').style.display = 'none'; document.getElementById('real-btn-box').style.display = 'none';
let readDom = document.getElementsByClassName('real-container')[0]; let readDom = document.getElementsByClassName('real-container')[0];
readDom.style.width = '100%'; readDom.style.width = '100%';
readDom.style.marginLeft = '0px';
document.getElementById('ws-real-player').style.marginBottom = '0px';
} }

@ -28,7 +28,7 @@
position: absolute; position: absolute;
} }
.ws-player .wsplayer-item.selected { .ws-player .wsplayer-item.selected {
border: 1px solid #009cff; /* border: 1px solid #009cff; */
transition: all cubic-bezier(0.19, 1, 0.22, 1) .3s; transition: all cubic-bezier(0.19, 1, 0.22, 1) .3s;
} }
.ws-player .wsplayer-item.unselected { .ws-player .wsplayer-item.unselected {

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

@ -12,7 +12,12 @@
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }
@font-face {
font-family: 'Alibaba-PuHuiTi-Heavytwo';
src: url('../font/大屏标题.OTF') format('truetype');
font-weight: normal;
font-style: normal;
}
body { body {
height: 100%; height: 100%;
margin: 0; margin: 0;

@ -61,6 +61,9 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.text-tooltip{
width: 100%;
}
:deep(.is-light) { :deep(.is-light) {
font-size: 20px !important; font-size: 20px !important;
} }

@ -4,7 +4,7 @@
<router-view v-slot="{ Component, route }"> <router-view v-slot="{ Component, route }">
<transition name="fade-transform" mode="out-in"> <transition name="fade-transform" mode="out-in">
<keep-alive :include="tagsViewStore.cachedViews"> <keep-alive :include="tagsViewStore.cachedViews">
<component v-if="!route.meta.link" :is="Component" :key="route.path"/> <component v-if="!route.meta.link" :is="Component" :key="route.fullPath"/>
</keep-alive> </keep-alive>
</transition> </transition>
</router-view> </router-view>

@ -28,6 +28,7 @@ import locale from 'element-plus/lib/locale/lang/zh-cn' // 中文语言
import vue3SeamlessScroll from 'vue3-seamless-scroll'; import vue3SeamlessScroll from 'vue3-seamless-scroll';
import elementIcons from '@/components/SvgIcon/svgicon' import elementIcons from '@/components/SvgIcon/svgicon'
import util from '@/components-zbry/utils' import util from '@/components-zbry/utils'
import texttooltip from '@/components/texttooltip'
const app = createApp(App) const app = createApp(App)
// 懒加载组件 // 懒加载组件
@ -55,6 +56,7 @@ app.component('BaseFilter', BaseFilter)
app.component('BaseModel', BaseModel) app.component('BaseModel', BaseModel)
app.component('BaseSelect', BaseSelect) app.component('BaseSelect', BaseSelect)
app.component('BaseControl', BaseControl) app.component('BaseControl', BaseControl)
app.component('texttooltip', texttooltip)
app.component('BaseTablePage', BaseTablePage) app.component('BaseTablePage', BaseTablePage)
app.component('BaseRadioGroup', BaseRadioGroup) app.component('BaseRadioGroup', BaseRadioGroup)
app.component('BaseUpload', BaseUpload) app.component('BaseUpload', BaseUpload)

@ -16,6 +16,7 @@ const indexArr = ["/index", "/"]
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
NProgress.start() NProgress.start()
if (getToken()) { if (getToken()) {
to.meta.title && useSettingsStore().setTitle(to.meta.title) to.meta.title && useSettingsStore().setTitle(to.meta.title)
/* has token*/ /* has token*/
if (to.path === '/login') { if (to.path === '/login') {

@ -131,6 +131,7 @@ function getList(params) {
// max-height: calc(100% - 150px); // max-height: calc(100% - 150px);
overflow: auto; overflow: auto;
/* 子元素超出宽度时换行 */ /* 子元素超出宽度时换行 */
} }
.app-container { .app-container {

@ -4,11 +4,25 @@
<div class="gradient"> <div class="gradient">
辽沈集团新火工区项目智慧工地数据看板 辽沈集团新火工区项目智慧工地数据看板
</div> </div>
<div class="xitong" @click="Jump()"></div> <div class="leftmenu">
<div style="background: none;justify-content: flex-start;line-height: 0rem;">
<span style="margin-top: .625rem;">
{{ state.time }}
</span>
</div>
<div :class="item.path == $route.path ? 'activeMenu' : ''" @click="resolvePath(item)"
v-for="item, index in meunList().slice(0, 2)">{{ item.meta.title }}
</div>
</div>
<div class="rightmenu">
<div @click="resolvePath(item)" v-for="item, index in meunList().slice(-3)">{{ item.meta.title }}</div>
</div>
<!-- <div class="xitong" @click="Jump()"></div> -->
</div> </div>
<div class="main-box"> <div class="main-box">
<div class="top-box"> <div class="bottom-box">
<!-- 项目介绍 --> <!-- 项目介绍 -->
<div class="right-top-item" style="overflow: hidden;">
<div class="top-item"> <div class="top-item">
<div class="boxtitle"> 项目介绍</div> <div class="boxtitle"> 项目介绍</div>
<div class="boxcontent" style="display: flex;flex-direction: column;padding: .9375rem 1.25rem;"> <div class="boxcontent" style="display: flex;flex-direction: column;padding: .9375rem 1.25rem;">
@ -22,67 +36,7 @@
项目简介本项目拟新建单体包括一期5305#5601#5806#5826#5827#7310#等6栋单体建筑二期5602#5606#5607#5606#5609#5610#5701#5801#5801-1#5802#5802-1#5803#5805#5807#5808#5810#5810-1#5811#5811-1#5812#5813#5815#5816#5816-1#5817#5818#5821#5822#5828#5829#5830#5831#5909#等34栋单体建筑建筑物基础形式为杯形基础独立基础条形基础主体结构为框架结构排架结构抗爆间室屏院墙体为钢筋混凝土剪力墙结构 项目简介本项目拟新建单体包括一期5305#5601#5806#5826#5827#7310#等6栋单体建筑二期5602#5606#5607#5606#5609#5610#5701#5801#5801-1#5802#5802-1#5803#5805#5807#5808#5810#5810-1#5811#5811-1#5812#5813#5815#5816#5816-1#5817#5818#5821#5822#5828#5829#5830#5831#5909#等34栋单体建筑建筑物基础形式为杯形基础独立基础条形基础主体结构为框架结构排架结构抗爆间室屏院墙体为钢筋混凝土剪力墙结构
</div> </div>
</div> </div>
</div>
<!-- 数据概览 -->
<div class="top-item">
<div class="boxtitle">数据概览</div>
<div class="boxcontent">
<div class="overview-top">
<div class="data-font">
<span class="number-font">{{ state.gk.list }} <span></span></span>
<span>总工期</span>
</div>
<div class="data-font jbborder">
<span class="number-font">{{ parseFloat(state.gk.gcjd).toFixed(0)
}}<span>%</span></span>
<span>工程进度</span>
</div>
<div class="data-font jbborder">
<span class="number-font">{{ state.gk.ysg }}<span></span></span>
<span>已施工</span>
</div>
</div>
<div class="overview-top" style="grid-template-columns: repeat(2, 1fr);border-bottom: 0;">
<div class="data-font ">
<span class="number-font">{{ state.gk.sg }}<span></span></span>
<span>施工人员</span>
</div>
<div class="data-font jbborder">
<span class="number-font">{{ state.gk.gl }}<span></span></span>
<span>管理人员</span>
</div>
</div>
</div>
</div>
<!-- 智能资源调度 -->
<div class="top-item">
<div class="boxtitle">智能资源调度</div>
<div class="boxcontent" style="display: flex;flex-direction: column;justify-content: space-around;">
<div class="zanwu" v-if="state.dispatchList.length == 0">
<img style="width: 9.375rem;" src="../../assets/images/zw.png" alt="">
<div class="zwtext">
暂无资源调度
</div>
</div>
<div v-for="item, index in state.dispatchList.slice(0, 2)">
<div class="jd-title">
<span style="margin-right: auto;">{{ item.planName }}</span>
<div>
<span>进度</span>
<span style="margin-left: .625rem;font-weight: bold;">{{ item.currentProgress
}}%</span>
</div>
</div>
<div style="width: 100%;margin: .5rem 0;"><el-progress class="jdt" color="#1FFFDA"
:text-inside="true" :stroke-width="12" :percentage="Number(item.currentProgress)">
<span></span>
</el-progress></div>
<div class="jgbox">
<img src="../../assets/images/jg.png" alt="">
{{ item.advises }}
</div>
</div>
</div>
</div> </div>
<!-- 工程日志 --> <!-- 工程日志 -->
<div class="top-item"> <div class="top-item">
@ -100,7 +54,8 @@
<div class="tq-box"> <div class="tq-box">
<img src="../../assets/images/wd.png" alt=""> <img src="../../assets/images/wd.png" alt="">
<span>温度</span> <span>温度</span>
<span v-if="state.logList && state.logList.length > 0">{{ state.logList[0].temperature <span v-if="state.logList && state.logList.length > 0">{{
state.logList[0].temperature
}}</span> }}</span>
<span v-else>-</span> <span v-else>-</span>
</div> </div>
@ -150,8 +105,132 @@
</div> </div>
</div> </div>
</div> </div>
<div class="bottom-box"> <!-- 视频监控 -->
<div class="right-top-item" style="overflow: hidden;"> <div class="center-top-item">
<div class="boxtitle changtitle">视频监控</div>
<div class="center-item bigbj">
<myVideo></myVideo>
<!-- <div class="alarm-table-header">
<div>序号</div>
<div>姓名</div>
<div>进出门类型</div>
<div>刷卡时间</div>
<div>人员类型</div>
<div>是否佩戴口罩</div>
<div>是否超温</div>
</div>
<div class="scooll-box" ref="Access">
<vue3-seamless-scroll :copyNum="10" :wheel="true" style="height: 100%;overflow: hidden;"
:scrollbar="{
type: 'mini',
invert: false,
}" :list="state.tableData" :hoverStop="true" :hover="true" :step="0.3">
<div v-for="item, index in state.tableData" :key="index"
:class="index % 2 != 0 ? 'dark' : 'light'" class="table-item">
<div>{{ index + 1 }}</div>
<div>
{{ item.personName }}
</div>
<div>{{ stausList().find((res) =>
res.value == item.openType)?.label || '-' }}</div>
<div>
{{ item.startSwingTime }}
</div>
<div>{{ item.imageType == 1 ? '内部人员' : item.imageType == 2 ? '访客' : '-' }}</div>
<div
:style="{ color: item.maskState == 2 ? '#FF0A0A' : item.maskState == 3 ? '#00E287' : '#fff' }">
{{ item.maskState == 3 ? '带口罩' : item.maskState == 2 ? '没带口罩' : '未识别' }}
</div>
<div :style="{ color: item.overTemp ? '#FF0A0A' : '#00E287' }">
{{ item.overTemp ? '是' : '否' }}
</div>
</div>
<div class="zanwu" v-if="state.tableData.length == 0">
<img style="width: 12.5rem;" src="../../assets/images/zw.png" alt="">
<div class="zwtext">
暂无门禁记录
</div>
</div>
</vue3-seamless-scroll>
</div> -->
</div>
</div>
<!-- 数据概览 and 施工人员工种分析 -->
<div class="right-top-item">
<div class="top-item" style="overflow: hidden;">
<div class="boxtitle">数据概览</div>
<div class="boxcontent">
<div class="overview-top">
<div class="data-font">
<span class="number-font">{{ state.gk.list }} <span></span></span>
<span>总工期</span>
</div>
<div class="data-font jbborder">
<span class="number-font">{{ parseFloat(state.gk.gcjd).toFixed(0)
}}<span>%</span></span>
<span>工程进度</span>
</div>
<div class="data-font jbborder">
<span class="number-font">{{ state.gk.ysg }}<span></span></span>
<span>已施工</span>
</div>
</div>
<div class="overview-top" style="grid-template-columns: repeat(2, 1fr);border-bottom: 0;">
<div class="data-font ">
<span class="number-font">{{ state.gk.sg }}<span></span></span>
<span>施工人员</span>
</div>
<div class="data-font jbborder">
<span class="number-font">{{ state.gk.gl }}<span></span></span>
<span>管理人员</span>
</div>
</div>
</div>
</div>
<div class="top-item">
<div class="boxtitle">施工人员工种分析</div>
<div class="boxcontent" id="staff">
</div>
</div>
</div>
</div>
<div class="top-box">
<!-- 智能资源调度 -->
<div class="top-item">
<div class="boxtitle">智能资源调度</div>
<div class="boxcontent" style="display: flex;flex-direction: column;justify-content: space-around;">
<div class="zanwu" v-if="state.dispatchList.length == 0">
<img style="width: 9.375rem;" src="../../assets/images/zw.png" alt="">
<div class="zwtext">
暂无资源调度
</div>
</div>
<div v-for="item, index in state.dispatchList.slice(0, 2)">
<div class="jd-title">
<span style="margin-right: auto;">{{ item.planName }}</span>
<div>
<span>进度</span>
<span style="margin-left: .625rem;font-weight: bold;">{{ item.currentProgress
}}%</span>
</div>
</div>
<div style="width: 100%;margin: .5rem 0;"><el-progress class="jdt" color="#1FFFDA"
:text-inside="true" :stroke-width="12" :percentage="Number(item.currentProgress)">
<span></span>
</el-progress></div>
<div class="jgbox">
<img src="../../assets/images/jg.png" alt="">
{{ item.advises }}
</div>
</div>
</div>
</div>
<!-- 进度预警 -->
<div class="top-item"> <div class="top-item">
<div class="boxtitle">进度预警</div> <div class="boxtitle">进度预警</div>
<div class="boxcontent" v-if="state.warnList.length == 0"> <div class="boxcontent" v-if="state.warnList.length == 0">
@ -182,7 +261,7 @@
</div> </div>
</div> </div>
<!-- 进度监控 --> <!-- 进度监控 -->
<div class="top-item" style="overflow: hidden;"> <div class="top-item">
<div class="boxtitle">进度监控</div> <div class="boxtitle">进度监控</div>
<div class="center-item"> <div class="center-item">
<div class="alarm-table-header" style=" grid-template-columns: 1.5fr 2.5fr 3fr 2.5fr;"> <div class="alarm-table-header" style=" grid-template-columns: 1.5fr 2.5fr 3fr 2.5fr;">
@ -218,74 +297,20 @@
</vue3-seamless-scroll> </vue3-seamless-scroll>
</div> </div>
</div> </div>
</div>
</div>
<!-- 门禁记录 -->
<div class="center-top-item">
<myVideo></myVideo>
<!-- <div class="boxtitle">门禁记录</div>
<div class="center-item">
<div class="alarm-table-header">
<div>序号</div>
<div>姓名</div>
<div>进出门类型</div>
<div>刷卡时间</div>
<div>人员类型</div>
<div>是否佩戴口罩</div>
<div>是否超温</div>
</div>
<div class="scooll-box" ref="Access">
<vue3-seamless-scroll :copyNum="10" :wheel="true" style="height: 100%;overflow: hidden;"
:scrollbar="{
type: 'mini',
invert: false,
}" :list="state.tableData" :hoverStop="true" :hover="true" :step="0.3">
<div v-for="item, index in state.tableData" :key="index"
:class="index % 2 != 0 ? 'dark' : 'light'" class="table-item">
<div>{{ index + 1 }}</div>
<div>
{{ item.personName }}
</div>
<div>{{ stausList().find((res) =>
res.value == item.openType)?.label || '-' }}</div>
<div>
{{ item.startSwingTime }}
</div>
<div>{{ item.imageType == 1 ? '内部人员' : item.imageType == 2 ? '访客' : '-' }}</div>
<div
:style="{ color: item.maskState == 2 ? '#FF0A0A' : item.maskState == 3 ? '#00E287' : '#fff' }">
{{ item.maskState == 3 ? '带口罩' : item.maskState == 2 ? '没带口罩' : '未识别' }}
</div>
<div :style="{ color: item.overTemp ? '#FF0A0A' : '#00E287' }">
{{ item.overTemp ? '是' : '否' }}
</div>
</div>
<div class="zanwu" v-if="state.tableData.length == 0">
<img style="width: 12.5rem;" src="../../assets/images/zw.png" alt="">
<div class="zwtext">
暂无门禁记录
</div>
</div>
</vue3-seamless-scroll>
</div>
</div> -->
</div>
<!-- 施工人员工种分析 and 车辆机械设备统计 -->
<div class="right-top-item">
<div class="top-item">
<div class="boxtitle">施工人员工种分析</div>
<div class="boxcontent" id="staff">
</div> </div>
</div>
<!-- 车辆机械设备统计 -->
<div class="top-item"> <div class="top-item">
<div class="boxtitle">车辆机械设备统计</div> <div class="boxtitle">车辆机械设备统计</div>
<div class="boxcontent" id="car"> <div class="boxcontent" id="car">
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>
<promptfrom></promptfrom> <promptfrom></promptfrom>
</div> </div>
@ -298,6 +323,7 @@ import { echartsZhu, echartsBing } from "./echartsOptions";
import { echart } from "../../echarts"; import { echart } from "../../echarts";
import { stausList } from './options' import { stausList } from './options'
import { retryAndRepeatRequest } from "@/utils/vctgo"; import { retryAndRepeatRequest } from "@/utils/vctgo";
import { meunList } from './options'
import { getRecordPage, iengineerlogList, iuserworkerType, iresourcescheduleList, vehiclestat, statistics, dataOverview, iwarnlist } from './api' import { getRecordPage, iengineerlogList, iuserworkerType, iresourcescheduleList, vehiclestat, statistics, dataOverview, iwarnlist } from './api'
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const tableTrue = ref(false); const tableTrue = ref(false);
@ -454,12 +480,14 @@ const state = reactive({
"ysg": 0, "ysg": 0,
gcjd: "" gcjd: ""
}, },
requestController: null requestController: null,
time: null,
}) })
onUnmounted(() => { onUnmounted(() => {
if (state.requestController) state.requestController.stop(); if (state.requestController) state.requestController.stop();
}); });
onMounted(async () => { onMounted(async () => {
getTime()
if (state.requestController) { if (state.requestController) {
state.requestController.stop(); state.requestController.stop();
state.requestController = null state.requestController = null
@ -493,6 +521,17 @@ onMounted(async () => {
state.requestController = retryAndRepeatRequest(requestFn, 3, 30000, 300000); state.requestController = retryAndRepeatRequest(requestFn, 3, 30000, 300000);
state.loading = false state.loading = false
}) })
function getTime() {
state.time = proxy.parseTime(new Date());
setTimeout(() => {
getTime();
}, 1000);
}
function resolvePath(item) {
router.push({
path: item.children && item.children.length > 0 ? (item.path + '/' + item.children[0].path) : item.path
})
}
function Jump() { function Jump() {
router.push({ router.push({
path: "/constructionScheduling/productionPlan" path: "/constructionScheduling/productionPlan"
@ -574,6 +613,46 @@ function engineeringLog(params) {
</script> </script>
<style scoped lang='scss'> <style scoped lang='scss'>
.leftmenu {
width: 32.5rem;
height: 2.5rem;
position: absolute;
left: 1.25rem;
bottom: -.3125rem;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
font-size: .9375rem;
color: #fff;
line-height: 2.5rem;
}
.rightmenu>div,
.leftmenu>div {
background: url('../../assets/images/menu.png') no-repeat;
background-size: 100% 100%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.activeMenu {
background: url('../../assets/images/menutwo.png') no-repeat !important;
}
.rightmenu {
line-height: 2.5rem;
width: 32.5rem;
height: 2.5rem;
position: absolute;
right: 1.25rem;
bottom: -.3125rem;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
font-size: .9375rem;
color: #fff;
}
.xitong { .xitong {
width: 6.25rem; width: 6.25rem;
height: 2.1875rem; height: 2.1875rem;
@ -698,18 +777,24 @@ function engineeringLog(params) {
height: calc(100% - 3rem); height: calc(100% - 3rem);
width: 100%; width: 100%;
margin-top: .5rem; margin-top: .5rem;
background: url('../../assets/images/cneterbj.png') no-repeat; background: url('../../assets/images/datacontentbj.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
overflow: hidden; overflow: hidden;
padding: 1.25rem; padding: 1.25rem;
} }
.bigbj {
background: url('../../assets/images/bigbj.png') no-repeat;
background-size: 100% 100%;
padding-left: .625rem;
}
.dark { .dark {
background: rgba(50, 165, 210, 0.15); background: rgba(50, 165, 210, 0.15);
} }
.light { .light {
background: rgba(50, 165, 210, 0.05); background: none;
} }
.right-top-item { .right-top-item {
@ -727,7 +812,7 @@ function engineeringLog(params) {
.bottom-box { .bottom-box {
width: 100%; width: 100%;
height: calc(66.66% - 1.25rem); height: calc(66.66% - 1.25rem);
margin-top: 1.25rem;
display: grid; display: grid;
grid-template-columns: 1fr 2fr 1fr; grid-template-columns: 1fr 2fr 1fr;
grid-gap: 1.25rem; grid-gap: 1.25rem;
@ -740,7 +825,7 @@ function engineeringLog(params) {
font-weight: 400; font-weight: 400;
font-size: .875rem; font-size: .875rem;
color: #FFFFFF; color: #FFFFFF;
background-color: #08223b; // background: rgba(50,165,210,0.4);
/* 深蓝色背景,可根据实际需求调整颜色值 */ /* 深蓝色背景,可根据实际需求调整颜色值 */
} }
@ -893,15 +978,17 @@ function engineeringLog(params) {
.boxtitle { .boxtitle {
width: 100%; width: 100%;
height: 2.5rem; height: 2.5rem;
line-height: 2.5rem;
background: url('../../assets/images/datatitle.png') no-repeat; background: url('../../assets/images/datatitle.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold; font-weight: bold;
font-size: 1rem; font-size: 1rem;
color: #FFFFFF; color: #FFFFFF;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 1.5625rem; padding: 0 2.375rem;
font-family: 'Alibaba-PuHuiTi-Heavytwo';
font-style: italic;
} }
.top-item { .top-item {
@ -912,6 +999,7 @@ function engineeringLog(params) {
.top-box { .top-box {
width: 100%; width: 100%;
height: 33.33%; height: 33.33%;
margin-top: 1.25rem;
display: grid; display: grid;
grid-template-columns: repeat(4, 1fr); grid-template-columns: repeat(4, 1fr);
grid-gap: 1.25rem; grid-gap: 1.25rem;
@ -927,7 +1015,8 @@ function engineeringLog(params) {
.topheader { .topheader {
width: 100%; width: 100%;
height: 6.25rem; height: 4.6875rem;
margin-bottom: 1.5625rem;
background: url('../../assets/images/datatopbj.png') no-repeat; background: url('../../assets/images/datatopbj.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
display: flex; display: flex;
@ -942,13 +1031,21 @@ function engineeringLog(params) {
background: linear-gradient(270.0000000000008deg, #F2F7FF 0%, #D4F7FF 50%, #F2F7FF 100%); background: linear-gradient(270.0000000000008deg, #F2F7FF 0%, #D4F7FF 50%, #F2F7FF 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
font-size: 2rem; font-size: 2.125rem;
font-weight: bold;
}
.changtitle {
background: url('../../assets/images/changtitle.png') no-repeat;
background-size: 100% 100%;
} }
.data-screen { .data-screen {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
background: #040614; background: url('../../assets/images/databj.png') no-repeat;
background-size: 100% 100%;
background-color: black;
// height: 67.5rem; // height: 67.5rem;
} }
</style> </style>

@ -62,3 +62,9 @@ export const stausList = () => {
{ "value": 10002, "label": "异常健康码开门" } { "value": 10002, "label": "异常健康码开门" }
] ]
} }
import usePermissionStore from '@/store/modules/permission'
const permissionStore = usePermissionStore()
export const meunList = () => {
let list = permissionStore.sidebarRouters.filter((item) => !item.hidden)
return list
}

@ -105,6 +105,8 @@ onMounted(() => {
"pageSize": 100, "pageSize": 100,
}).then((res) => { }).then((res) => {
state.cameraList = res.data.pageData state.cameraList = res.data.pageData
const index = state.cameraList.findIndex(item => item.isOnline === 1);
state.currentCameraIndex = index
}).catch((err) => { }).catch((err) => {
}); });
@ -112,6 +114,7 @@ onMounted(() => {
window.addEventListener('message', (event) => { window.addEventListener('message', (event) => {
console.log('event :>> ', event.data); console.log('event :>> ', event.data);
if (event.data.type === 'startVideo') { if (event.data.type === 'startVideo') {
startVideo(); startVideo();
} else if (event.data.type === 'playRecord') { } else if (event.data.type === 'playRecord') {
playRecord(event.data.date); playRecord(event.data.date);
@ -122,59 +125,85 @@ onMounted(() => {
</script> </script>
<template> <template>
<div class="app-container"> <div class="app-containertwo">
<!-- 监控摄像头名称列表 --> <!-- 监控摄像头名称列表 -->
<div class="camera-name-list"> <div class="camera-name-list">
<template v-for="(camera, index) in state.cameraList" :key="index"> <!-- -->
<span <div :class="state.currentCameraIndex === index ? 'active' : ''" @click="switchCamera(index)" class="camera-item"
class="camera-name" v-for="(camera, index) in state.cameraList" :key="index">
@click="switchCamera(index)" <div style="width:3.75rem;margin-right: 1.25rem;text-align: center;position: relative;">
:class="{ active: state.currentCameraIndex === index }" <texttooltip :content="camera.deviceName" :class="state.currentCameraIndex === index ? 'wid202' : 'wid201'"
> refName=" tooltipOverd"></texttooltip>
<el-tag style="scale: 0.7;position: absolute;top:-20px;right:-.9375rem;border-radius: 1.25rem;"
:type="camera.isOnline == 1 ? 'success' : 'danger'">{{ camera.isOnline == 1 ? '在线' : '离线' }}</el-tag>
</div>
</div>
<!-- <template v-for="(camera, index) in state.cameraList" :key="index">
<span class="camera-name" @click="switchCamera(index)" :class="{ active: state.currentCameraIndex === index }">
{{ camera.deviceName }} {{ camera.deviceName }}
<el-tag style="scale: 0.8;position: absolute;top: -10px;right:-15px;border-radius: 20px;" :type="camera.isOnline == 1 ? 'success':'danger'">{{ camera.isOnline == 1 ? '在线' : '离线' }}</el-tag>
</span> </span>
</template> </template> -->
</div> </div>
<!-- 摄像头展示区域 --> <!-- 摄像头展示区域 -->
<div class="camera-display"> <div class="camera-display">
<iframe id="video" src="/dahua/demo.html?real=true" style="width:100%;height:100%;" frameborder="0"></iframe> <iframe v-if="state.cameraList.length > 0" id="video" src="/dahua/demo.html?real=true"
<!-- <video style="width:100%;height:100%;" frameborder="0"></iframe>
v-if="state.currentCameraIndex !== -1"
:src="cameraList[state.currentCameraIndex].source"
controls
autoplay
muted
></video> -->
<!-- <p v-else>请选择摄像头</p> -->
</div> </div>
</div> </div>
</template> </template>
<style scoped> <style scoped>
.app-container { .wid202 {
background: linear-gradient(90deg, #FFFFFF 0%, #FFF8C2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.wid201 {
background: linear-gradient(90deg, #FFFFFF 0%, #45B1FE 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.camera-item {
cursor: pointer;
width: 100%;
background: url('../../assets/images/videoitembj.png') no-repeat;
background-size: 100% 100%;
/* margin-top: -1.25rem; */
display: flex;
flex-shrink: 0;
height: 3.125rem;
align-items: center;
justify-content: flex-end;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: .875rem;
margin-bottom: .625rem;
color: #fff;
}
.app-containertwo {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
padding: 20px; height: 100%;
height: calc(100vh - 135px); padding: 0;
} }
.camera-name-list { .camera-name-list {
display: flex; width: 11.875rem;
gap: 15px;
margin-bottom: 20px;
flex-wrap: wrap;
justify-content: center;
width: 130px;
height: 100%; height: 100%;
margin-right: 1.25rem;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden;
} }
.camera-name { .camera-name {
padding: 8px 32px; padding: .5rem 2rem;
border: 1px solid #ccc; border: .0625rem solid #ccc;
border-radius: 20px; border-radius: 1.25rem;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
background-color: white; background-color: white;
@ -183,23 +212,21 @@ onMounted(() => {
.camera-name:hover { .camera-name:hover {
background-color: #e0e0e0; background-color: #e0e0e0;
transform: translateY(-2px); transform: translateY(-.125rem);
} }
.camera-name.active { .active {
background-color: #2196F3; background: url('../../assets/images/videoitembjtwo.png') no-repeat;
background-size: 100% 100%;
/* background-color: #2196F3;
color: white; color: white;
border-color: #2196F3; border-color: #2196F3; */
} }
.camera-display { .camera-display {
width: 100%; width: 100%;
height: 100%; height: 100%;
box-sizing: border-box; box-sizing: border-box;
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
} }
video { video {
@ -210,6 +237,6 @@ video {
p { p {
text-align: center; text-align: center;
color: #666; color: #666;
font-size: 18px; font-size: 1.125rem;
} }
</style> </style>

Loading…
Cancel
Save