济菏高速业务端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

633 lines
17 KiB

<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"
@click="onRefreshData"
>刷新</el-button
>
<el-button
size="mini"
icon="el-icon-download"
class="btnSearch"
@click="SystemStatusExport"
>导出Excel</el-button
>
</div>
<div class="right-div">
<InputSearch
:formList="searchFormList"
@handleSearch="handleSearch"
/>
<!-- :placeholder="searchText" -->
</div>
</div>
<div class="queryChart">
<!-- v-if="isEmpty01" -->
<Empty
v-if="isEmpty01"
class="floatEmpty"
:text="emptyText01"
></Empty>
<div ref="queryChart" class="keep-ratio"></div>
</div>
<div style="position: relative">
<Empty
v-if="isEmpty02"
class="floatEmpty"
:text="emptyText02"
></Empty>
<el-table
:border="false"
:data="tableData"
height="480"
header-align="left"
empty-text=" "
>
<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-1'">高清网络枪型固定摄像机</div>
<div v-if="scope.row.type == '1-2'">高清网络球形摄像机</div>
<div v-if="scope.row.type == '1-3'">桥下高清网络球形摄像机</div>
<div v-if="scope.row.type == '1-4'">360°全景摄像机</div>
<div v-if="scope.row.type == '1-5'">180°全景摄像机</div>
<div v-if="scope.row.type == '2-1'">门架式可变信息标志</div>
<div v-if="scope.row.type == '2-3'">雨棚可变信息标志</div>
<div v-if="scope.row.type == '2-4'">站前悬臂式可变信息标志</div>
<div v-if="scope.row.type == '3'">气象检测器</div>
<div v-if="scope.row.type == '5'">路段语音广播系统</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 == '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>
</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" style="color: #bbb">
离线
</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 {
searchText: "请设置查询条件",
isEmpty01: true,
emptyText01: "请输入参数查询...",
isEmpty02: true,
emptyText02: "请输入参数查询...",
startTime: "",
time: "",
typeQuery: "", //高清网络枪型固定摄像机
pageTotal: 0,
pageIndex: 1,
pageSize: 10,
searchFormList,
equipSeries: [
"高清网络球形摄像机",
"360°全景摄像机",
"门架式可变信息标志",
"站前悬臂式可变信息标志",
"气象检测器",
"合流区预警系统",
"高清网络枪型固定摄像机",
"智能设备箱",
"毫米波雷达",
"路段语音广播系统",
"护碰撞预警系统",
"激光疲劳唤醒系统",
"180°全景摄像机",
"一类交通量调音站",
"雨棚可变信息标志",
"智能行车诱导系统",
],
equipments: [],
activeName: "first",
tableData: [],
interval: null,
};
},
destroyed() {
clearInterval(this.interval);
},
methods: {
initData() {
this.startTime = moment().startOf("month").format("YYYY-MM-DD HH:mm:ss");
this.time = moment().format("YYYY-MM-DD HH:mm:ss");
this.typeQuery = this.searchFormList[1].options.options[0].value;
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.initQueryChart();
this.initQueryTable(1);
}
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";
},
onRefreshData() {
if (!this.typeQuery || !this.startTime) {
this.$message({
message: "请先设置查询条件!",
type: "warning",
});
return;
}
this.initQueryChart();
this.initQueryTable(1);
},
handleSearch(data) {
console.log(777, data);
this.typeQuery = data.type;
this.startTime = moment(data.time[0]).format("YYYY-MM-DD HH:mm:ss");
this.time = moment(data.time[1]).format("YYYY-MM-DD HH:mm:ss");
let typeText =
this.searchFormList[1].options.options[this.typeQuery - 1]?.label;
this.searchText = `${moment(this.startTime).format(
"YYYY年MM月DD日"
)}-${moment(this.time).format("YYYY年MM月DD日")},${typeText}`;
this.initQueryChart();
this.initQueryTable(1);
},
changeTabs() {
this.initData();
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();
});
},
initDevice() {
//设备在线离线率接口
getSystemStatusType().then((res) => {
if (IS_TESTING && (!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;
console.log("Equipments", allList);
});
},
setStatus(id, status) {
if (status == "doing") {
this["isEmpty" + id] = true;
this["emptyText" + id] = "数据查询中...";
} else if (status == "empty") {
this["isEmpty" + id] = true;
this["emptyText" + id] = "暂无数据...";
} else if (status == "finish") {
this["isEmpty" + id] = false;
this["emptyText" + id] = "";
}
},
initQueryChart() {
this.setStatus("01", "doing");
getSystemStatusList({
startTime: this.startTime,
time: this.time,
type: this.typeQuery,
}).then((res) => {
if (res.code == 200) {
if (res.data && Object.keys(res.data).length > 0) {
this.setStatus("01", "finish");
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);
});
} else {
this.setStatus("01", "empty");
}
}
});
},
//查询列表
initQueryTable(pageIndex, pageSize = 30) {
this.setStatus("02", "doing");
getSystemStatusTabList({
startTime: this.startTime,
time: this.time,
type: this.typeQuery,
pageNum: pageIndex,
pageSize: pageSize,
}).then((res) => {
if (res.code == 200) {
if (res.rows && res.rows.length > 0) {
this.setStatus("02", "finish");
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;
});
} else {
this.setStatus("02", "empty");
}
}
});
},
},
async mounted() {
await this.initData();
},
};
</script>
<style lang="scss" scoped>
.floatEmpty {
position: absolute;
z-index: 100;
background: rgba($color: #000000, $alpha: 0.2);
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.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;
padding-left: 15px;
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;
}
.queryChart {
position: relative;
display: inline-flex;
width: 100%;
height: 343px;
margin-top: 20px;
padding: 0 20px;
background: linear-gradient(180deg, rgba(6, 66, 88, 0) 0%, #06425860 100%);
margin-bottom: 30px;
--keep-ratio: scaleX(1);
> 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>