<template> <Teleport> <div class="mask"> <transition> <div v-if="visible" class="content"> <div class="mainDialog"> <div class="dialog_head"> <div class="tit">{{ selectedDevice.deviceName }}</div> <img class="btnCls" src="@/assets/jihe/images/dialog/ibCls.png" alt="" @click="____onClose" /> <img class="deco" src="@/assets/jihe/images/dialog/ibHeadDeco.png" alt="" /> </div> <div class="dialogContent"> <div v-if="selectedBdMsg.length > 0" class="dialogContent_box" style="height: 100%"> <vuescroll :ops="scrollOptions" class="listBox"> <div v-for="(itm, indx) in selectedBdMsg" :key="indx" class="tplItem"> <!-- 模板内容 --> <BoardPreview class="boardPreview" :boardWH="selectedSize" :tpl="itm"></BoardPreview> <!-- 操作按钮 --> <div class="infoBtnBox"> <el-tooltip content="编辑" placement="top"> <p @click="____onEditBoardItem(itm, indx)" class="btn btnEdit"></p> </el-tooltip> <el-tooltip content="删除" placement="top"> <p @click="____onDeleteBoardItem(indx)" class="btn btnDelete"></p> </el-tooltip> </div> </div> </vuescroll> </div> <div v-else class="dialogContent_box" style="height: 100%"> <div class="dialogContent_box_empty">暂无数据</div> </div> <div class="dialogContent_bottom"> <el-tabs v-model="activeTab" @tab-click="tabClickFn"> <el-tab-pane label="详情信息" name="first"> <div class="show_bottom_tab_box"> <div class="deviceInfo"> <div class="deviceInfo_l">设备名称</div> <div class="deviceInfo_r"> {{ selectedDevice.deviceName }} </div> </div> <div class="deviceInfo"> <div class="deviceInfo_l">设备桩号</div> <div class="deviceInfo_r"> {{ selectedDevice.stakeMark }} </div> </div> <div class="deviceInfo"> <div class="deviceInfo_l">屏幕像素</div> <div class="deviceInfo_r"> {{ JSON.parse(selectedDevice.otherConfig).screenSize }} px </div> </div> <!-- <div class="deviceInfo" v-for="item in tabDataInfoList" :key="item.id"> <div class="deviceInfo_l">{{ item.tit }}: </div> <div class="deviceInfo_r" :style="{ 'color': item.col }"> {{ item.txt }}</div> </div> --> </div> </el-tab-pane> <el-tab-pane label="设备参数" name="second">设备参数</el-tab-pane> <el-tab-pane label="在线率统计" name="third">在线率统计</el-tab-pane> </el-tabs> </div> <div class="dialogContent_bottom_btn"> <el-button class="btnInfoBoard" type="add" @click.native="____onAddDeviceItem()">添加信息</el-button> <el-button class="btnInfoBoard" type="publish" @click="____publishInfo" :disabled="selectedBdMsg.length <= 0 || selectedDevice.iotDeviceId === null || selectedDevice.iotDeviceId === undefined">发布信息</el-button> </div> <div class="sideSwitch" @click="____onShowTemplate"> <img class="img" src="@/assets/screen/xtb/leftd.png" alt="" :style="{ transform: isShowTemplate ? 'rotate(0deg)' : 'rotate(180deg)', }" /> <div class="txt">信息模板</div> </div> <!-- 附近的摄像机 --> <div class="sideSwitch" style="top: 36%" @click="____onShowCameraShower"> <img class="img" src="@/assets/screen/xtb/leftd.png" alt="" :style="{ transform: dialogInfoCamera ? 'rotate(0deg)' : 'rotate(180deg)', }" /> <div class="txt">附近相机</div> </div> </div> </div> <!-- 信息模板 --> <div v-if="isShowTemplate" class="sideContent template"> <vuescroll :ops="scrollOptions" class="listBox"> <div v-for="(item, index) in templateAvailable" :key="item.dictValue"> <!-- 原来是<el-collapse v-model="activeNames"> --> <h3>{{ item.dictLabel }}</h3> <div v-for="(itm, indx) in item.list" :key="indx" class="tplItem"> <!-- 模板内容 --> <BoardTplPreview class="boardPreview" :boardWH="selectedSize" :tpl="itm"></BoardTplPreview> <!-- <div class="infoPreview"> <div class="infoBox" :style="____boardBgStyle"> <span class="infoTxt" :style="____boardTxtStyle(itm)" v-html="itm.content.replace(/\n|\r\n/g, '<br>').replace(/ /g, ' ')"></span> </div> </div> --> <!-- 操作按钮 --> <div class="infoBtnBox infoBtnBoxSm"> <el-tooltip content="加入待下发信息" placement="top"> <p @click="____onTplToDevice(itm, false)" class="btn btnApply"></p> </el-tooltip> </div> </div> </div> </vuescroll> </div> <!-- 附近相机 --> <CameraShower class="sideContent camera" :visible.sync="dialogInfoCamera" :list="nearbyCameraList"> </CameraShower> </div> </transition> <BoardInfoEditor @afterSubmit="____onEditSubmit" :mode="editDialog.mode" :type="editDialog.type" :visible.sync="editDialog.visible" :screenSize="selectedSize" :tpl="editDialog.tpl"></BoardInfoEditor> </div> </Teleport> </template> <script> import { listDevice, invokedFunction, getDeviceRealtimeProperty, } from "@/api/device/device.js"; // import infoBoardTestData from "@/common/infoBoardTestData.js" import { getBoardDeviceInfo } from "@/api/board/board"; import { getNearbyCameraByPileNum } from "@/api/camera/camera"; import BoardPreview from "@screen/components/infoBoard/BoardPreview.vue"; import BoardTplPreview from "@screen/components/infoBoard/BoardTplPreview.vue"; import BoardInfoEditor from "@screen/components/infoBoard/BoardInfoEditor"; import vuescroll from "vuescroll"; import scrollOptions from "@/common/scrollbar.js"; import Teleport from "@screen/components/Teleport.vue"; import { getTemplateList } from "@/api/board/template"; import testDeviceInfo from "@screen/testData/infoBoard.js"; import CameraShower from "@screen/components/CameraShower"; import InfoBoard from "@screen/mixins/InfoBoard"; export default { name: "InfoBoard", mixins: [InfoBoard], data() { return { isShowTemplate: false, dialogInfoCamera: false, dialogInfoList: [], moBanList: [], activeNames: [1001, 1002], activeTab: "first", tabDataInfoList: [], cameraDataVideoList: [], cameraDataList: [ { id: 3001, txt: "设备名称", val: "疲劳唤醒设备1" }, { id: 3002, txt: "设备编号", val: "G00030497B0180001" }, { id: 3003, txt: "设备桩号", val: "K097+900" }, { id: 3004, txt: "经/纬度", val: "117.071152/35.910659" }, { id: 3005, txt: "道路名称", val: "G35济菏高速" }, { id: 3006, txt: "道路状况", val: "正常" }, { id: 3007, txt: "方向", val: "菏泽" }, ], cameraBtnList: [ { id: 4001, cmd: 23, dir: "left", le: "26%", to: "33%", ro: 0 }, { id: 4002, cmd: 21, dir: "up", le: "46%", to: "4%", ro: 90 }, { id: 4003, cmd: 24, dir: "right", le: "65%", to: "33%", ro: 180 }, { id: 4004, cmd: 22, dir: "downward", le: "46%", to: "62%", ro: 267 }, ], cameraControlList: [ { id: 5001, txt: "变倍", numL: 11, numR: 12 }, { id: 5002, txt: "光圈", numL: 16, numR: 15 }, { id: 5003, txt: "聚焦", numL: 14, numR: 13 }, ], selectedBdMsg: [], selectedSize: "", editDialog: { mode: "", type: "", visible: false, tpl: {}, }, scrollOptions, templateAvailable: null, tplCategory: [], //模板 templateAll: [], nearbyCameraList: [], }; }, props: { visible: { type: Boolean, default: false, }, selectedDevice: { type: Object, default: null, }, }, watch: { selectedDevice: { handler(newV) { this.____initData(); }, immediate: true, }, }, components: { BoardPreview, BoardTplPreview, BoardInfoEditor, vuescroll, Teleport, CameraShower, }, created() { // this.____getTemplateCategory(); // this.____getAllTemplate(); }, computed: {}, mounted() { }, methods: { // 获取信息模板分类 ____getTemplateCategory() { return this.getDicts("iot_template_category").then((res) => { this.tplCategory = res.data; }); }, //获取全部模版 ____getAllTemplate() { return getTemplateList().then((res) => { this.templateAll = res.data; }); }, //初始化数据 ____initData() { this.selectedSize = JSON.parse( this.selectedDevice.otherConfig ).screenSize; if (this.tplCategory.length && this.templateAll.length) { this.____setAvailableTemplate(); } else { Promise.all([ this.____getTemplateCategory(), this.____getAllTemplate(), ]).then((res) => { this.____setAvailableTemplate(); }); } this.____getDeviceInfo(); }, // 获取已选中设备的展示内容 ____getDeviceInfo() { if (IS_TESTING) { this.selectedBdMsg = _.cloneDeep(testDeviceInfo.data["3A"].content); } else { //改下判断条件 iotDeviceId为null时不要请求后台 加个提示 设备未接入 const iotDeviceId = this.selectedDevice.iotDeviceId; if (!(iotDeviceId === null || iotDeviceId === undefined)) getBoardDeviceInfo() .then((res) => { this.selectedBdMsg = res.data["3A"].content; }) .catch((err) => { }); else this.$message.error("设备未接入"); } }, // 设置当前设备可用的模板 ____setAvailableTemplate() { this.templateAvailable = []; this.tplCategory.forEach((item, index) => { let arr = this.templateAll["" + index]; if (arr.length > 0) { let temp = []; arr.forEach((tpl) => { if (tpl.screenSize == this.selectedSize) { temp.push(tpl); } }); if (temp.length > 0) { this.templateAvailable.push({ ...item, list: temp, }); } } }); }, //调用编辑器编辑设备展示项 ____onEditBoardItem(tpl, index) { // type : board template // mode : edit add toDevice toTemplate this.boardItemEdtingIndex = index; this.editDialog = { visible: true, mode: "edit", type: "device", tpl, }; }, //删除设备展示项 ____onDeleteBoardItem(index) { if (index > -1) { this.selectedBdMsg.splice(index, 1); this.$message.success("删除成功。"); } }, //编辑机编辑后的回调 ____onEditSubmit(para) { this.editDialog.tpl = {}; this.editDialog.visible = false; if (para.type == "device") { if (para.mode == "edit") { this.selectedBdMsg[this.boardItemEdtingIndex] = para.data; } else { this.selectedBdMsg.push(para.data); } } else if (para.mode == "toDevice") { this.selectedBdMsg.push(para.data); } else { this.____refreshPageData(para); } }, ____refreshPageData(para) { }, ____getNearbyCams() { if (!this.selectedDevice.stakeMark) { this.$message.warning("设备缺少stakeMark字段..."); } let stakeMark = this.selectedDevice.stakeMark; // stakeMark = "K64+300"; getNearbyCameraByPileNum(stakeMark).then((res) => { this.nearbyCameraList = res.data; }); }, cameraControlBtnFn(item) { this.getEnergyCameraControlFn(item.cmd, 5); }, cameraControlLeFn(item) { // console.log('按钮点击事件', item) this.getEnergyCameraControlFn(item, 5); }, getEnergyCameraControlFn(cmd, spe) { getEnergyCameraControlAPi({ camId: this.cameraVal, cmdType: cmd, speed: spe, }).then((res) => { // console.log('控制返回结果', res) // this.videoUrl = res.data.liveUrl }); }, cameraValChangeFn() { console.log("点击切换按钮", this.cameraVal); this.cameraValCha(this.cameraOptList, this.cameraVal); }, // cameraDataVideoList cameraValCha(date, num) { let str = { 0: "正常", 1: "网络中断", 2: "网络正常无图像", 3: "有图像图可能存在问题", }; date.forEach((i) => { if (i.camId === num) { this.cameraDataVideoList = [ { id: 3001, txt: "设备名称", val: i.camName }, { id: 3002, txt: "设备编号", val: i.camId }, { id: 3003, txt: "设备桩号", val: i.pileNum }, { id: 3005, txt: "道路名称", val: i.deptName }, { id: 3006, txt: "道路状况", val: i.status == "-1" ? "未启用" : str[Number(i.status)], }, ]; } }); }, tabClickFn(tab, event) { console.log(tab, event); }, ____onClose() { this.$emit("update:visible", false); this.isShowTemplate = false; }, ____onShowTemplate() { if (this.dialogInfoCamera) { this.dialogInfoCamera = false; } this.isShowTemplate = !this.isShowTemplate; }, ____onShowCameraShower() { if (this.isShowTemplate) { this.isShowTemplate = false; } this.dialogInfoCamera = !this.dialogInfoCamera; this.____getNearbyCams(); }, subjectBtnFn(item) { this.subjectBtn = item.id; }, }, }; </script> <style lang="scss" scoped> .listBox { padding: 20px; .tplItem { margin-right: 14px; display: flex; align-items: stretch; padding-bottom: 10px; .boardPreview { border: 1px solid rgba(61, 232, 255, 0.5); // width: 560px; // height:80px; flex: 1; } .infoBtnBox { &.infoBtnBoxSm { width: 60px; } width: 110px; height: 80px; display: flex; margin-left: 10px; /* // border: solid 1px #05afe3; */ border: 1px solid rgba(61, 232, 255, 0.5); display: flex; justify-content: space-around; align-items: center; .btn { background-repeat: no-repeat; background-size: 100% 100%; width: 30px; height: 30px; &.btnApply { background-image: url(~@/assets/jihe/images/button/toLeft.svg); } &.btnEdit { background-image: url(~@/assets/jihe/images/button/edit.svg); } &.btnDelete { background-image: url(~@/assets/jihe/images/button/delete.svg); } } i { font-size: 24px; color: #666; padding-left: 4px; cursor: pointer; caret-color: rgba(0, 0, 0, 0); user-select: none; } i:hover { color: #05afe3; } .disabledClass { pointer-events: none; cursor: auto !important; color: #ccc; } } } .controlBox { margin-top: 10px; margin-bottom: 10px; display: flex; justify-content: center; } .el-collapse { max-height: 100% !important; overflow: auto; border-bottom: none; border-top: none; padding: 0 0.5vw; } } .mask { width: 100%; height: 100%; position: fixed; top: 0; left: 0; background: rgba(0, 0, 0, 0.36); z-index: 1100; display: flex; justify-content: center; align-items: center; .content { display: flex; flex-direction: row; } } .mainDialog { width: 510px; height: 620px; background-color: #114c66; margin-right: 3px; } .sideContent { border: 2px solid #196980; background-color: #114c66; position: relative; margin-top: 50px; &.camera { width: 540px; height: 556px; } &.template { width: 430px; height: 556px; padding: 20px 0 20px 10px; } } .dialog_head { width: 100%; height: 48px; padding: 0 10px; background-image: url("~@/assets/screen/xtb/qbbtit.png"); background-size: 100% 100%; background-repeat: no-repeat; background-position: center; position: relative; display: flex; justify-content: space-between; align-items: center; .tit { color: #3de8ff; font-size: 18px; } .btnCls { width: 13px; height: 13px; cursor: pointer; } .deco { width: 55%; height: 5px; position: absolute; left: 0; top: 0; } } .dialogContent { width: 100%; height: 300px; padding: 10px 24px 10px 10px; position: relative; } .dialogContent_box { width: 100%; // height: 100%; overflow-y: scroll; } .dialogContent_l { width: 355px; // height: 4.91vh; border: 2px solid #1d7890; padding: 1px 0; display: flex; justify-content: center; align-items: center; } .dialogContent_r { width: 96px; // height: 4.91vh; border: 2px solid #1d7890; display: flex; justify-content: space-around; align-items: center; } .dialogContent_l_xsq { width: 256px; height: 100%; font-size: 18px; color: #ff0000; background-color: #000; line-height: 1; // text-align: center; display: flex; // justify-content: center; align-items: center; } .show_r_btn { width: 1.67vw; height: 2.96vh; cursor: pointer; } .dialogContent_r_btn1 { background-image: url("~@/assets/screen/xtb/gg.png"); background-size: 100% 100%; background-repeat: no-repeat; background-position: center; } .dialogContent_r_btn2 { background-image: url("~@/assets/screen/xtb/xx.png"); background-size: 100% 100%; background-repeat: no-repeat; background-position: center; } .dialogContent_r_btn3 { background-image: url("~@/assets/screen/xtb/zz.png"); background-size: 100% 100%; background-repeat: no-repeat; background-position: center; } .dialogContent_box_item { margin-bottom: 0.5vh; display: flex; justify-content: space-between; } .dialogContent_bottom { width: 105%; height: 16.52vh; } .deviceInfo { width: 50%; padding: 10px 0; display: flex; // flex-wrap: wrap; align-items: stretch; } .show_bottom_tab_box { width: 100%; display: flex; flex-wrap: wrap; align-items: center; } .deviceInfo_l { color: #3de8ff; font-size: 14px; width: 70px; display: flex; flex-direction: row; align-items: center; } .deviceInfo_r { width: 0; flex: 1; color: #fff; font-size: 14px; margin-left: 0.5vw; } .sideSwitch { position: absolute; right: 0%; top: 0%; width: 24px; line-height: 1.2; padding: 0.5vh 0; background: linear-gradient(180deg, #005c79 0%, #009bcc 100%); border-radius: 0px 0px 0px 0px; opacity: 1; text-align: center; cursor: pointer; .img { width: 15px; height: 10px; border: none; transition: transform 0.3s ease; /* 过渡效果 */ } .txt { color: #fff; font-size: 13px; } } .dialogContent_box_empty { font-size: 14px; text-align: center; color: #fff; } .dialog_info_right_tit { color: #fff; font-size: 14px; margin-bottom: 0.5vh; } .dialog_info_right_show { width: 100%; // height: 28vh; } .dialogContent_bottom_btn { height: 28px; display: flex; justify-content: flex-end; align-items: center; text-align: center; } .info_right_camera { width: 100%; height: calc(100% - 4vh); padding: 1vh 0.5vw; } .info_right_camera_top { width: 100%; height: 20vh; } .info_right_camera_bom { width: 100%; padding: 1vh 0; height: calc(100% - 20vh); display: flex; } .camera_bom_left { width: 50%; height: 100%; padding: 2vh 0; border-right: 1px dashed #285a71; } .camera_bom_right { width: 50%; height: 100%; } .camera_bom_left_item { width: 100%; color: #fff; display: flex; font-size: 14px; padding-bottom: 1.5vh; } .camera_bom_left_item_txt { width: 31%; color: #3de8ff; } .camera_bom_left_item_val { color: #fff; font-size: 13px; } .camera_bom_right_t { width: 100%; height: 60%; position: relative; } .camera_bom_right_b { width: 100%; height: 40%; // background-color: deeppink; } .camera_bom_right_t_box { width: 2vw; height: 4vh; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); background-color: #005f87; border-radius: 50%; border: 1px solid #2191b1; } .camera_bom_right_t_h_po { width: 1vw; height: 5vh; position: absolute; left: 27%; top: 33%; cursor: pointer; background-image: url("~@/assets/screen/xtb/xjleft.png"); background-size: 100% 100%; background-repeat: no-repeat; background-position: center; } .camera_bom_right_b_btn { width: 100%; padding: 0vh 2vw 1vh 2vw; display: flex; justify-content: space-between; } .camera_bom_right_b_btn_l { width: 1.2vw; height: 2.4vh; border-radius: 50%; background-image: url("~@/assets/screen/xtb/jhbtn.png"); background-size: 100% 100%; background-repeat: no-repeat; background-position: center; cursor: pointer; } .camera_bom_right_b_btn_c { color: #fff; } .camera_bom_right_b_btn_r { width: 1.2vw; height: 2.4vh; border-radius: 50%; background-image: url("~@/assets/screen/xtb/addbtn.png"); background-size: 100% 100%; background-repeat: no-repeat; background-position: center; cursor: pointer; } // background-color: #104b65; // background-image: url('~@/assets/screen/xtb/qbbtit.png'); // background-size: 100% 100%; // background-repeat: no-repeat; // background-position: center; /* 通用滚动条样式 */ ::-webkit-scrollbar { width: 3px; /* 设置滚动条宽度 */ height: 3px; /* 设置滚动条高度 */ } ::-webkit-scrollbar-track { background-color: #114c66; /* 设置滚动条轨道颜色 */ } ::-webkit-scrollbar-thumb { background-color: #9abce0; /* 设置滚动条滑块颜色 */ border-radius: 4px; /* 设置滚动条滑块圆角 */ } ::v-deep .el-tabs__nav-wrap::after { background-color: #316076; } ::v-deep .el-tabs__item.is-active { color: #3de8ff !important; } ::v-deep .el-tabs__item { color: #fff !important; } ::v-deep .el-tabs__active-bar { background-color: #3de8ff !important; } ::v-deep .el-collapse-item__header { color: #fff; height: 28px; background-color: #053b4f; border: none; padding-left: 0.5vw; } ::v-deep .el-collapse { color: #fff; border: none; } ::v-deep .el-collapse-item__wrap { color: #fff; will-change: height; background-color: #053b4f; overflow: hidden; -webkit-box-sizing: border-box; box-sizing: border-box; margin-top: 0.5vh; border: none; } ::v-deep .el-collapse-item__content { margin-bottom: 0; padding: 0.5vh 0.5vw; } ::v-deep .el-collapse-item { margin-bottom: 1vh; } ::v-deep .el-input--mini .el-input__icon { line-height: 20px; color: #fff; } </style>