<template> <div class='statisticAnalysis'> <el-tabs class="saContent" v-model="activeName" @tab-click="changeTabs"> <el-tab-pane label="设备分析" name="first" class="deviceAnalysis"> <DeviceSummary class="deviceSummary" :dataList="equipments"></DeviceSummary> <div class="bottomTabs"> <DeviceUptime :dataList="equipments" class="tabs-lo" /> <MonthlyEquipment class="tabs-mo" :dataList="equipments" /> </div> </el-tab-pane> <el-tab-pane label="设备查询" name="second"> <div class="topdiv"> <div class="left-div"> <el-button size="mini" icon="el-icon-refresh-left" class="btnSearch">刷新</el-button> <el-button size="mini" icon="el-icon-download" class="btnSearch" @click="SystemStatusExport">导出Excel</el-button> </div> <div class="right-div"> <InputSearch style="width: 402px;" :formList="searchFormList" @handleSearch="handleSearch" /> </div> </div> <div class="middleDiv"> <div ref="queryChart" class="keep-ratio"> </div> </div> <div> <el-table :border="false" :data="tableData" height="480" style="width: 100%"> <el-table-column prop="order" label="序号" width="80"> </el-table-column> <el-table-column prop="deviceName" label="设备名称"></el-table-column> <el-table-column prop="deviceNo" label="设备桩号" width=""> </el-table-column> <el-table-column prop="direction" label="方向" class-name="showClass" width=""> </el-table-column> <el-table-column prop="deviceIp" label="设备IP" width=""> </el-table-column> <el-table-column prop="production" label="厂家" width=""> </el-table-column> <el-table-column prop="type" label="型号" width=""> <template slot-scope="scope"> <div v-if="scope.row.type == 1">高清网络枪型固定摄像机</div> <div v-if="scope.row.type == 2">高清网络球形摄像机</div> <div v-if="scope.row.type == 3">桥下高清网络球形摄像机</div> <div v-if="scope.row.type == 4">360°全景摄像机</div> <div v-if="scope.row.type == 5">180°全景摄像机</div> <div v-if="scope.row.type == 6">门架式可变信息标志</div> <div v-if="scope.row.type == 7">雨棚可变信息标志</div> <div v-if="scope.row.type == 8">站前悬臂式可变信息标志</div> <div v-if="scope.row.type == 9">气象检测器</div> <div v-if="scope.row.type == 10">路段语音广播系统</div> <div v-if="scope.row.type == 11">护栏碰撞预警系统</div> <div v-if="scope.row.type == 12">毫米波雷达</div> <div v-if="scope.row.type == 13">合流区预警系统</div> <div v-if="scope.row.type == 14">激光疲劳唤醒</div> <div v-if="scope.row.type == 15">一类交通量调查站</div> <div v-if="scope.row.type == 16">智能行车诱导系统</div> <div v-if="scope.row.type == 17">智能设备箱</div> </template> </el-table-column> <el-table-column prop="network" label="网段" width=""> </el-table-column> <el-table-column prop="time" label="监测时间" width=""> </el-table-column> <el-table-column prop="deviceStatus" label="操作" width=""> <template slot-scope="scope"> <div v-if="scope.row.deviceStatus == 1">在线</div> <div v-if="scope.row.deviceStatus == 0">离线</div> </template> </el-table-column> </el-table> <div class="foot"> <Pagination @current-change="changePage" width="'100%'" :page-size="pageSize" :current-page.sync="pageIndex" layout="total, sizes, prev, pager, next" :total="pageTotal"> </Pagination> </div> </div> </el-tab-pane> </el-tabs> </div> </template> <script> import * as echarts from "echarts"; import chartsStatistics from "./assets/charts"; import DeviceUptime from './components/deviceUptime'; import MonthlyEquipment from './components/monthlyEquipment'; import DeviceSummary from './components/deviceSummary'; import { getSystemStatusList, getSystemStatusTabList, getSystemStatusType, getSystemStatusExport } from "../../../../../api/MonthlyEquipment"; import { download } from '../../../../../utils/request.js'; import Pagination from '@screen/components/Pagination.vue'; import InputSearch from '@screen/components/InputSearch/index.vue'; import { searchFormList } from "./data"; import { Loading } from 'element-ui'; import { first } from "lodash"; export default { name: 'publicService', components: { DeviceUptime, MonthlyEquipment, Pagination, InputSearch, DeviceSummary }, data() { return { startTime: "2024-01-01 00:00:00", time: "2024-01-31 00:00:00", typeQuery: 1, //高清网络枪型固定摄像机 pageTotal: 0, pageIndex: 1, pageSize: 10, searchFormList, equipSeries: [ "高清网络球形摄像机", "360°全景摄像机", "门架式可变信息标志", "站前悬臂式可变信息标志", "气象检测器", "合流区预警系统", "高清网络枪型固定摄像机", "智能设备箱", "毫米波雷达", "路段语音广播系统", "护碰撞预警系统", "激光疲劳唤醒系统", "180°全景摄像机", "一类交通量调音站", "雨棚可变信息标志", "智能行车诱导系统", ], equipments: [], activeName: "second", tableData: [{ date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", }, { date: '2023-12-31 13:00:00', name: '高清网络球形摄像机', address: 'K234+235', root: "中央分隔带", ip: "10.0.61.43", cj: "海康威视", xh: "XXX", wd: "梁山收费站监控网段", jcsj: "2024-01-17", cz: "在线", } ], interval: null } }, destroyed() { clearInterval(this.interval); }, methods: { initData() { clearInterval(this.interval); if (this.activeName == "first") { this.initDevice(); } else if (this.activeName == 'second') { this.queryChart = echarts.init(this.$refs["queryChart"]); this.queryChart.setOption(chartsStatistics); // this.initQueryTable(1); // this.initQueryChart(); } this.interval = setInterval(() => { if (this.activeName == "first") { this.initDevice(); } }, 30000) }, changePage(page) { this.initQueryTable(page); }, formatDate(val) { let year = val.getFullYear(); var m = val.getMonth() + 1; var day = val.getDate(); m = m < 10 ? "0" + m : "" + m; day = day < 10 ? "0" + day : "" + day; return year + "-" + m + "-" + day + " 00:00:00"; }, handleSearch(data) { this.typeQuery = data.type; this.startTime = this.formatDate(data.time[0]); this.time = this.formatDate(data.time[1]); this.initQueryChart(); this.initQueryTable(1); }, changeTabs() { this.initData(); console.log("======================", this.queryChart); this.$nextTick(() => { this.queryChart.resize(); }); }, //导出 SystemStatusExport() { let loadingInstance = Loading.service({ fullscreen: true, background: "#00000052", text: "文件正在下载..." }); getSystemStatusExport({ startTime: this.startTime, time: this.time, type: this.typeQuery, }).then((res) => { console.log(res); const url = window.URL.createObjectURL(new Blob([res])) let link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', '设备统计信息.xlsx') document.body.appendChild(link) link.click() URL.revokeObjectURL(link.href) // 释放URL 对象 document.body.removeChild(link) link = null loadingInstance.close(); }).catch(err => { Message.error(err); loadingInstance.close(); }) }, initQueryChart() { getSystemStatusList({ startTime: this.startTime, time: this.time, type: this.typeQuery, }).then((res) => { if (res.code == 200) { let origin = res.data; let startStamp = +moment(this.startTime).startOf('day').format("x"); let endStamp = +moment(this.time).endOf('day').format("x"); let oneDay = 86400000; let daysTotal = Math.ceil((endStamp - startStamp) / oneDay); let queryChartData = []; let dataX = []; let data0 = []; let data1 = []; for (let i = 0; i < daysTotal; i++) { let ts = startStamp + i * oneDay; let date = moment(ts).format("YYYY-M-D"); let val = origin[date] ? +origin[date].replace("%", "") : 0; dataX.push(moment(ts).format("MM月DD日")); data0.push(val); data1.push(100); } chartsStatistics.xAxis.data = dataX; chartsStatistics.series[0].data = data0; chartsStatistics.series[1].data = data1; chartsStatistics.yAxis[0].name = "在线率(%)"; this.$nextTick(() => { this.queryChart.setOption(chartsStatistics); }); } }) }, initDevice() { //设备在线离线率接口 getSystemStatusType().then((res) => { if (!res.data || res.msg == "暂无数据") { this.equipments = []; this.equipSeries.forEach(item => { this.equipments.push({ title: item, total: Math.floor(Math.random() * 600) + 800, pctOnl: Math.floor(100 * Math.random()) + "%", pctOffl: "25%", pctLose: "15%" }); }); return; } let allList = []; for (let key in res.data) { let val = res.data[key]; let item = { title: key, total: val.sum, pctOnl: val.sucessRate, pctLose: val.failRate, pctOffl: val.lostRate } if (key.includes("全部设备")) { allList.unshift(item); } else { allList.push(item); } } this.equipments = allList; }) }, //查询列表 initQueryTable(pageIndex, pageSize = 30) { getSystemStatusTabList({ startTime: this.startTime, time: this.time, type: this.typeQuery, pageNum: pageIndex, pageSize: pageSize, }).then((res) => { if (res.code == 200) { this.pageIndex = pageIndex; this.pageSize = pageSize; this.pageTotal = res.total; this.tableData = res.rows; this.tableData.forEach((it, index) => { it.order = (pageIndex - 1) * (pageSize) + index + 1; }) } }) } }, mounted() { this.initData(); }, } </script> <style lang='scss' scoped> .bottomTabs { position: relative; display: inline-flex; width: 100%; flex-direction: row; height: 100%; .tabs-lo { display: inline-flex; width: 670px; margin-right: 15px; } .tabs-mo { display: inline-flex; flex: 1; } } .deviceSummary { height: 390px; margin-bottom: 10px; } .btnSearch { background: linear-gradient(180deg, #005C79 0%, #009BCC 100%); margin-left: 10px; border-color: transparent; color: #fff; } ::v-deep .el-table .cell { padding-left: 0px !important; } ::v-deep .el-table .el-table__header-wrapper th { background-color: #064258 !important; color: #00D1FF; border-color: #064258 !important; border: 0px !important; font-size: 14px; font-family: PingFang SC, PingFang SC; font-weight: 500; } ::v-deep .el-table { border: 0px !important; background-color: transparent; font-size: 12px !important; } ::v-deep .el-table__body-wrapper { background-color: #064258; color: #fff; } ::v-deep .el-table .el-table__cell { height: 47px; font-size: 14px; font-family: PingFang SC, PingFang SC; font-weight: 500; color: #FFFFFF; } ::v-deep .el-table tr:hover td { background: #1b2528 !important; color: #00D1FF; height: 47px; } ::v-deep .el-table tr:nth-child(odd) td { background-color: #13272F; border: 0px !important; } ::v-deep .el-table tr:nth-child(even) td { border: 0px !important; } ::v-deep .el-table tr { background-color: #133242 !important; border-collapse: 0; border: 0px !important; background-color: transparent !important; } ::v-deep .el-tabs__item { display: inline-flex; justify-content: center; font-size: 16px; font-family: PingFang SC, PingFang SC; font-weight: 500; color: #FFFFFF; min-width: 128px; position: relative; left: 10px; } ::v-deep .el-tabs__active-bar { min-width: 128px; } ::v-deep .el-tabs__nav-wrap::after { background-color: #133242; opacity: 0.1; } .saContent { width: 100%; height: 100%; .deviceAnalysis {} } .topdiv { display: inline-flex; position: relative; width: 100%; height: 40px; justify-content: space-between; align-items: center; .right-div { display: inline; width: 450px; } } .statisticAnalysis { padding: 8px 20px; .header-shot { width: 98%; margin: auto; margin-top: 15px; height: 160px; } .middleDiv { display: inline-flex; width: 100%; height: 343px; background: linear-gradient(180deg, rgba(6, 66, 88, 0) 0%, #06425860 100%); margin-bottom: 30px; >div { display: inline-flex; width: 100%; height: 100%; } } .content { width: 100%; margin: auto; display: flex; flex: 1; pointer-events: none; margin-top: 19px; >div { pointer-events: auto; } .content-l { width: calc(25%); margin-right: 20px; } .content-mi { width: calc(50%); margin-right: 20px; } .content-m { display: inline-flex; flex-direction: column; width: calc(100% / 4); margin-right: 20px; .content-m-t { width: 100%; height: 240px; margin-bottom: 20px; } } .content-r { width: 49.4%; } } } </style>