<template> <view style="overflow: auto; height: 100%"> <!-- 建议放在外层 --> <u-navbar :title="name" @leftClick="backPage" :bgImage="backPic" :bgStatusImage="backPic0" > <view class="u-nav-slot" slot="left"> <u-icon name="arrow-left" size="20"> </u-icon> </view> </u-navbar> <view class="main"> <view class="u-page container"> <div class="button-grid flcard" v-if="this.TabCur == 'gate'"> <u-button type="primary" text="打开前门" @click="showPasswordDialog('frontGateOpen_S')" ></u-button> <u-button type="primary" text="关闭前门" @click="showPasswordDialog('frontGateClose_S')" ></u-button> <u-button type="primary" text="打开后门" @click="showPasswordDialog('rearGateOpen_S')" ></u-button> <u-button type="primary" text="关闭后门" @click="showPasswordDialog('rearGateClose_S')" ></u-button> <u-button type="primary" text="打开前后门" @click="showPasswordDialog('sameTimeOpen')" ></u-button> <u-button type="primary" text="关闭前后门" @click="showPasswordDialog('sameTimeClose')" ></u-button> </div> <div class="button-grid flcard" v-if="this.TabCur == 'window' && this.nwindownum == 1" > <u-button type="primary" text="设定面积" @click="showPasswordDialog('frontSetValue')" ></u-button> </div> <div class="button-grid flcard" v-if="this.TabCur == 'window' && this.nwindownum == 2" > <u-button type="primary" text="设定前窗面积" @click="showPasswordDialog('frontSetValue')" ></u-button> <u-button type="primary" text="设定后窗面积" @click="showPasswordDialog('rearSetValue')" ></u-button> </div> <div class="flcard" v-if="this.TabCur == 'gate'"> <doorAnimate :gatestate1="frontGateStatus" :gatestate2="midGateStatus" :gatestate3="rearGateStatus" :cameralist="cameralist" :height="height" :doorcount="ndoorcount" ></doorAnimate> </div> <div class="flcard" v-if="this.TabCur == 'windrect'"> <windrectAnimate :state="state" :title="title" :videoURL="viedeoUrl" :height="height" :type="deviceType" ></windrectAnimate> </div> <div class="flcard" v-if="this.TabCur == 'fanlocal'"> <fanlocalAnimate :fan1State="fan1State" :fan2State="fan2State" :title="title" :videoURL="viedeoUrl" :height="height" ></fanlocalAnimate> </div> <div class="flcard" v-if="this.TabCur == 'fanmain'"> <fanmainAnimate ref="fanpage" style="width: 100%; min-width: 550px; height: calc(68vh - 220px)" :door1="door1" :topdoor1="topdoor1" :fundoor1="fundoor1" :door2="door2" :topdoor2="topdoor2" :fundoor2="fundoor2" :nowfengji="qidongfengji" ></fanmainAnimate> </div> <div class="flcard" v-if="this.TabCur == 'window' && this.nwindownum == 1" > <windowAnimate :windowAngle="windowAngle" :height="height" :windowcount="nwindownum" ></windowAnimate> </div> <div class="flcard" v-if="this.TabCur == 'window' && this.nwindownum == 2" > <windowAnimate :windowAngle="windowAngle" :windowAngle1="windowAngle1" :height="height" :windowcount="nwindownum" ></windowAnimate> </div> <div class="flcard"> <div class="flex-container"> <div class="itemback" v-for="(item, index) in typeList" :key="index" v-show="item.appShow == 1" > <div class="datacardtime" v-if="item.monitorcode == 'readTime'"> <view class="demo-layout bg-purple-light" style="padding: 20rpx; color: #3787fe" > {{ readTime }} </view> </div> <div class="datacard" v-if="item.monitorcode !== 'readTime'"> <div class="left-content"> <view v-if="item.monitorcode == 'ndoortype'" class="demo-layout bg-purple-light" style="margin-top: 10rpx; color: #3787fe" > {{ tableData[item.monitorcode] == "1" ? "行人" : tableData[item.monitorcode] == "2" ? "行车" : "-" }} </view> <view v-else-if="item.monitorcode == 'netStatus'" class="demo-layout bg-purple-light" style="margin-top: 10rpx; color: #3787fe" > {{ doorNetStatus == "1" ? "正常" : "异常" }} </view> <view v-else-if="item.monitorcode == 'warnFlag'" class="demo-layout bg-purple-light" style="margin-top: 10rpx; color: #3787fe" > {{ warnFlag == "1" ? "正常" : "异常" }} </view> <view v-else class="demo-layout bg-purple-light" style="margin-top: 10rpx; color: #3787fe" > {{ tableData[item.monitorcode] == null || tableData[item.monitorcode] == "" ? "-" : tableData[item.monitorcode] }} </view> <div class="spacer"></div> <!-- 间距 --> <view class="demo-layout bg-purple-light" style="color: #677799" > {{ item.des }} </view> </div> <div class="right-content" :style="{ backgroundImage: item.monitorcode === 'frontRearDP' || item.monitorcode === 'frontRearDifference' ? 'url(\'../../../../static/model/Pa.png\')' : item.monitorcode === 'sourcePressure' ? 'url(\'../../../../static/model/MPa.png\')' : item.monitorcode === 'frontGateOpen' ? 'url(\'../../../../static/model/doorNet.png\')' : item.monitorcode === 'rearGateOpen' ? 'url(\'../../../../static/model/doorNet.png\')' : item.monitorcode === 'midGateOpen' ? 'url(\'../../../../static/model/doorNet.png\')' : item.monitorcode === 'warnFlag' ? 'url(\'../../../../static/model/9432.png\')' : item.monitorcode === 'netStatus' ? 'url(\'../../../../static/model/9431.png\')' : item.monitorcode === 'm3' ? 'url(\'../../../../static/model/windM3.png\')' : item.monitorcode === 'fsectarea' ? 'url(\'../../../../static/model/duanArea.png\')' : item.monitorcode === 'incipientWindSpeed1' || item.monitorcode === 'incipientWindSpeed2' || item.monitorcode === 'incipientWindSpeed3' || item.monitorcode === 'va' ? 'url(\'../../../../static/model/fengsu.png\')' : 'url(\'\')', backgroundSize: '100% 100%', }" ></div> </div> </div> </div> </div> </view> </view> <u-popup :show="show" mode="bottom" :safeAreaInsetBottom="false"> <div class="containers"> <view class="passWordName"> <view class="title" style="margin-top: 15px" v-if="this.TabCur == 'window'" >风窗面积</view > <u-input class="passArea" style="margin-top: 15px; border-color: #2a94ff" v-model="windowArea" type="text" v-if="this.TabCur == 'window'" ></u-input> </view> <view class="passWordInput"> <view style="margin-top: 15px" class="title">输入密码</view> <u-input style="margin-top: 15px; border-color: #2a94ff" v-model="password" type="password" ></u-input ></view> </div> <view class="btns"> <u-button style="margin: 20px" type="primary" @click="confirmPassword()" color="linear-gradient(to right, rgb(53, 138, 254), rgb(38, 171, 244))" >确认</u-button > <u-button style="margin: 20px" type="primary" :plain="true" @click="cancelPassword()" >取消</u-button > </view> </u-popup> </view> </template> <script> import api from "@/api/api"; import initDictOptions from "@/common/util/dictUtil.js"; import doorAnimate from "../doorAnimate/doorAnimate.vue"; import windowAnimate from "../windowAnimate/windowAnimate.vue"; import windrectAnimate from "../windrectAnimate/windrectAnimate.vue"; import fanlocalAnimate from "../fanlocalAnimate/fanlocalAnimate2.vue"; import fanmainAnimate from "../fanmainAnimate/fanmainAnimate.vue"; export default { data() { return { tableData: [], //监测数据 typeList: [], //展示字段 itemId: "", // 初始化 itemId name: "", // 初始化 name deviceid: "", //初始化设备id TabCur: "", checked: [], backPic0: "url(/static/topnavbar0.png)", backPic: "url(/static/topnavbar.png)", frontAngle: "", //风窗打开角度 nwindownum: "", //风窗道数 ndoorcount: "", //风门道数 deviceType: "", //设备类型 show: false, //密码弹窗是否显示 password: "", //控制设备密码 paramcode: "", //控制字段 height: "200px", popupStyle: { // 弹窗样式 "background-color": "#fff", padding: "20px", "box-shadow": "0 2px 4px rgba(0, 0, 0, 0.1)", }, frontGateStatus: "", //前门状态 rearGateStatus: "", //后门状态 midGateStatus: "", //状态 doorNetStatus: "", //风门通信状态 warnFlag: "", //风门报警 readTime: "", //时间 windowAngle: 0, //前窗打开角度 windowAngle1: 0, //后窗打开角度 windowArea: "", //风窗面积设定值 viedeoUrl: "", //监控url sign: "", title: "测风设备", fan1State: "", fan2State: "", deviceid: "", //ID cameralist: [], //摄像数据 }; }, onLoad(query) { //保存id到 data 中 可以在整个页面中使用 this.itemId = query.id; this.name = query.name; this.TabCur = query.type; this.ndoorcount = 2; }, components: { doorAnimate, windowAnimate, windrectAnimate, fanlocalAnimate, fanmainAnimate, }, created() { this.getShowList(this.TabCur); this.getDeviceInfo(this.itemId); this.getVideoUrlById(this.itemId); }, mounted() { this.startTimer(); }, methods: { startTimer() { this.timer = setInterval(() => { // 执行定时任务 this.getDeviceInfo(this.itemId); }, 5000); }, stopTimer() { // 停止定时器 clearInterval(this.timer); }, // 返回上一个页面 backPage() { this.$destroy(); uni.navigateBack({ delta: 1, }); }, //获取app展示字段数据 getShowList(type) { const params = { devicekind: type, pagetype: "detail", pageNo: 1, pageSize: 100, }; new Promise((resolve, reject) => { api .getShowColumList(params) .then((response) => { if (response.data.code == 200) { this.typeList = response.data.result.records; } else { resolve(response); } }) .catch((error) => { reject(error); }); }); }, //获取详情数据 getDeviceInfo(ID) { let IDString = String(ID); // 将 ID 转换为字符串 new Promise((resolve, reject) => { api .getDeviceMonitor({ devicetype: this.TabCur, ids: IDString }) .then((response) => { if ( response.data.code == 200 && response.data.result.msgTxt[0].datalist.length > 0 ) { var result = response.data.result.msgTxt[0].datalist[0]; this.tableData = result.readData; if (this.tableData.frontGateOpen == "1") { this.tableData.frontGateOpen = "打开"; } else { this.tableData.frontGateOpen = "关闭"; } if (this.tableData.midGateOpen == "1") { this.tableData.midGateOpen = "打开"; } else { this.tableData.midGateOpen = "关闭"; } if (this.tableData.rearGateOpen == "1") { this.tableData.rearGateOpen = "打开"; } else { this.tableData.rearGateOpen = "关闭"; } this.fan1State = result.readData.Fan1StartStatus; this.fan2State = result.readData.Fan2StartStatus; this.nwindownum = result.nwindownum; this.ndoorcount = result.ndoorcount; this.deviceType = result.deviceType; this.state = result.readData.sign; this.frontGateStatus = this.tableData.frontGateOpen; this.midGateStatus = this.tableData.midGateOpen; this.rearGateStatus = this.tableData.rearGateOpen; this.doorNetStatus = result.netStatus; this.warnFlag = result.warnLevel_str; this.readTime = result.readTime; var maxarea = result.maxarea; this.windowAngle = (this.tableData.forntArea / maxarea) * 100 * 0.9; this.windowAngle1 = (this.tableData.rearArea / maxarea) * 100 * 0.9; this.deviceid = result.deviceID; this.$forceUpdate(); } else { resolve(response); } }) .catch((error) => { reject(error); }); }); }, //获取监控URL 通过ID获取 getVideoUrlById(ID) { let IDString = String(ID); // 将 ID 转换为字符串 new Promise((resolve, reject) => { api .getCameraById({ deviceid: IDString }) .then((response) => { if (response.data.code == 200) { if (response.data.result.records.length > 0) { this.cameralist = response.data.result.records[0]; } } else { resolve(response); } }) .catch((error) => { reject(error); }); }); }, //设备控制 ctrlDevice(pass) { let IDString = String(this.itemId); // 将 ID 转换为字符串 const params = { deviceid: IDString, devicetype: this.deviceType, paramcode: this.paramcode, password: pass, value: this.windowArea, }; new Promise((resolve, reject) => { api .controlDevice(params) .then((response) => { if (response.data.code == 200) { this.getDeviceInfo(IDString); // console.log("操作成功"); } else { resolve(response); } }) .catch((error) => { reject(error); }); }); }, // 显示密码输入弹窗 showPasswordDialog(controlCode) { this.paramcode = controlCode; this.show = true; }, // 取消密码输入 cancelPassword() { this.show = false; }, confirmPassword() { this.ctrlDevice(this.password); // 发起请求后关闭密码输入弹窗 this.show = false; }, }, destroyed() { // 停止定时器 this.stopTimer(); }, }; </script> <style lang="scss" scoped> .top-nav { background-image: url(../../../../static/topnavbar.png); background-size: cover; /* 背景图片大小适应 */ height: 100%; } .top-nav2 { background-color: #ffffff; } .main { margin-top: 80px; } .container { display: flex; flex-direction: column; } .button-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; /* 可以根据需要调整行列之间的间距 */ } .flcard { padding: 20rpx; background-color: #ffffff; margin-bottom: 5rpx; } .additional-div { grid-column: span 2; /* 让附加内容跨越三列 */ display: flex; align-items: center; } .checkbox-group { margin-left: 10px; /* 可以根据需要调整间距 */ } .card { background-color: #ffffff; margin: auto; margin-top: 20rpx; width: 90%; height: 280rpx; border: 1rpx solid #000000; border-radius: 20rpx; } .flex-containe { display: flex; flex-direction: row; flex-wrap: wrap; } .itemback { flex: 0 0 calc(33.33% - 10px); /* 使用calc函数计算每个项目的宽度,减去间距 */ margin: 5px; /* 间距设置为5px */ } .datacardtime { display: flex; width: 100%; flex: 1; margin: 1%; float: left; height: 50rpx; text-align: center; background: linear-gradient( to right, rgba(55, 135, 254, 0.08), rgba(4, 184, 255, 0.08), rgba(60, 161, 237, 0.08) ); } .datacard { display: flex; width: 48%; flex: 1; margin: 1%; float: left; height: 100rpx; text-align: center; background: linear-gradient( to right, rgba(55, 135, 254, 0.08), rgba(4, 184, 255, 0.08), rgba(60, 161, 237, 0.08) ); } .left-content { width: 50%; display: flex; flex-direction: column; } .spacer { height: 10rpx; } .right-content { width: 50%; /* 右侧内容占据50%宽度 */ background-image: url(../../../../static/model/Pa.png); background-size: 100% 125%; } /*风窗样式*/ div.autowindow_new { width: 200px; height: 200px; background-image: url(../../../../static/window/window-bk.png); background-size: 100% 100%; perspective: 800px; } /*风窗1 2 3 4*/ div.window_new_1 { margin-top: 12px; margin-left: 15px; width: 170px; height: 30px; background-color: crimson; box-sizing: border-box; float: left; z-index: 1; /* transition: all 2s; */ background-image: url(../../../../static/window/window_new1.png); background-size: 100% 100%; } div.window_new_2 { margin-top: 2px; margin-left: 15px; width: 170px; height: 29px; background-color: crimson; box-sizing: border-box; float: left; z-index: 1; /* transition: all 2s; */ background-image: url(../../../../static/window/window_new1.png); background-size: 100% 100%; } div.window_new_3 { margin-top: 2px; margin-left: 15px; width: 170px; height: 29px; background-color: crimson; box-sizing: border-box; float: left; z-index: 1; /* transition: all 2s; */ background-image: url(../../../../static/window/window_new1.png); background-size: 100% 100%; } div.window_new_4 { margin-top: 2px; margin-left: 15px; width: 170px; height: 29px; background-color: crimson; box-sizing: border-box; float: left; z-index: 1; /* transition: all 2s; */ background-image: url(../../../../static/window/window_new1.png); background-size: 100% 100%; } div.window_new_5 { margin-top: 2px; margin-left: 15px; width: 170px; height: 29px; background-color: crimson; box-sizing: border-box; float: left; z-index: 1; /* transition: all 2s; */ background-image: url(../../../../static/window/window_new1.png); background-size: 100% 100%; } div.window_new_1 { transition: all 2s ease; transform-origin: center center; } div.window_new_2 { transition: all 2s ease; transform-origin: center center; } div.window_new_3 { transition: all 2s ease; transform-origin: center center; } div.window_new_4 { transition: all 2s ease; transform-origin: center center; } div.window_new_5 { transition: all 2s ease; transform-origin: center center; } .btns { display: flex; } .containers { background-color: #fff; } .passWordName { margin: 20px; display: flex; flex-direction: row; justify-content: space-around; } .title { margin-right: 20px; line-height: 40px; } .passWordInput { margin: 20px; display: flex; flex-direction: row; justify-content: space-around; } .passArea { border-color: red; } </style>