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.
375 lines
14 KiB
375 lines
14 KiB
<template>
|
|
<div class="app-container">
|
|
<el-row :gutter="10">
|
|
<el-col :span="4">
|
|
<type-tree @defaultCheck="defaultCheck" @nodeCheck="nodeCheck" :filter="false" :show_checkbox="true" :default_check_first="true"></type-tree>
|
|
</el-col>
|
|
<el-col :span="20">
|
|
<el-row>
|
|
<el-date-picker
|
|
style="float: right"
|
|
v-model="dateRange"
|
|
size="mini"
|
|
@change="handleRangePickerChange"
|
|
value-format="yyyy-MM-dd HH:mm:ss"
|
|
type="daterange"
|
|
range-separator="至"
|
|
start-placeholder="开始日期"
|
|
end-placeholder="结束日期">
|
|
</el-date-picker>
|
|
<el-button type="primary" style="float: right;margin-right: 10px" size="mini" @click="handleExport">导出</el-button>
|
|
</el-row>
|
|
<line-chart height="30vh" :show-legend="true" :chart-data="chartData"></line-chart>
|
|
<el-table :data="tableData" height="42vh" style="width: 100%" @sort-change="handleSortChange">
|
|
<el-table-column prop="deviceName" label="设备名称" width="200"></el-table-column>
|
|
<el-table-column prop="stakeMark" label="桩号"></el-table-column>
|
|
<el-table-column prop="direction" label="方向">
|
|
<template slot-scope="scope">
|
|
<span v-if="scope.row.direction=='1'">菏泽方向</span>
|
|
<span v-else-if="scope.row.direction=='3'">济南方向</span>
|
|
<span v-else>双向</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="deviceIp" label="IP"></el-table-column>
|
|
<el-table-column prop="deviceStatus" label="状态">
|
|
<template slot-scope="scope">
|
|
<el-tag type="success" size="small" v-if="scope.row.deviceStatus=='1'">在线</el-tag>
|
|
<el-tag type="danger" size="small" v-else>离线</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="lossRate" label="丢包率">
|
|
<template slot-scope="scope">
|
|
<span v-if="scope.row.lossRate > 0" style="color: #ff4949">{{scope.row.lossRate}}</span>
|
|
<span v-else>{{scope.row.lossRate}}</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="rttAvg" label="平均时延"></el-table-column>
|
|
<el-table-column prop="networkQuality" label="网络质量">
|
|
<template slot-scope="scope">
|
|
<el-tag type="success" size="small" v-if="scope.row.networkQuality=='优'">优</el-tag>
|
|
<el-tag type="primary" size="small" v-if="scope.row.networkQuality=='良'">良</el-tag>
|
|
<el-tag type="warning" size="small" v-if="scope.row.networkQuality=='一般'">一般</el-tag>
|
|
<el-tag type="danger" size="small" v-if="scope.row.networkQuality=='差'">差</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<!-- <el-table-column prop="statisticalDate" label="日期"></el-table-column>-->
|
|
<el-table-column prop="onlineRate" label="在线率" sortable="custom">
|
|
<template slot-scope="scope">
|
|
<el-progress :percentage="scope.row.onlineRate"></el-progress>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column align="center">
|
|
<template slot="header" slot-scope="scope">
|
|
<el-popover placement="bottom" width="300" trigger="click">
|
|
<el-form :model="queryParams" ref="queryForm" size="small" label-width="68px">
|
|
<el-form-item label="设备桩号" prop="stakeMark">
|
|
<el-input size="mini" v-model="queryParams.stakeMark" placeholder="请输入设备桩号" clearable @keyup.enter.native="deviceOnlineTable"/>
|
|
</el-form-item>
|
|
<el-form-item label="使用状态" prop="useState">
|
|
<el-select size="mini" v-model="queryParams.useState" placeholder="请选择使用状态" clearable>
|
|
<el-option
|
|
v-for="item in useStateOptions"
|
|
:key="item.value"
|
|
:label="item.name"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="设备状态" prop="deviceState">
|
|
<el-select size="mini" v-model="queryParams.deviceState" placeholder="请选择设备状态" clearable>
|
|
<el-option
|
|
v-for="item in deviceStateOptions"
|
|
:key="item.value"
|
|
:label="item.name"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="IP地址" prop="deviceIp">
|
|
<el-input
|
|
size="mini"
|
|
v-model="queryParams.deviceIp"
|
|
placeholder="请输入IP地址"
|
|
clearable
|
|
@keyup.enter.native="deviceOnlineTable"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="deviceOnlineTable">搜索</el-button>
|
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
<el-button slot="reference" size="mini" icon="el-icon-search">搜索</el-button>
|
|
</el-popover>
|
|
</template>
|
|
<template slot-scope="scope" >
|
|
<el-button @click="seeLog(scope.row.deviceId)" type="text" size="mini" icon="el-icon-view">网络日志</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<pagination
|
|
v-show="total>0"
|
|
:total="total"
|
|
:page.sync="queryParams.pageNum"
|
|
:limit.sync="queryParams.pageSize"
|
|
@pagination="deviceOnlineTable"
|
|
/>
|
|
</el-col>
|
|
</el-row>
|
|
<el-dialog title="设备网络日志" width="80vw" :visible.sync="logVisible">
|
|
<el-row style="position: absolute;top: 45px;right: 40px">
|
|
<el-button size="mini" @click="upDay">上一日</el-button>
|
|
<el-button style="margin-right: 10px" size="mini" @click="downDay">下一日</el-button>
|
|
<el-date-picker
|
|
style="width: 130px"
|
|
v-model="logQueryParams.queryDate"
|
|
type="date"
|
|
size="mini"
|
|
value-format="yyyy-MM-dd"
|
|
placeholder="选择日期"
|
|
@change="logQuery"
|
|
>
|
|
</el-date-picker>
|
|
</el-row>
|
|
<el-row style="width: 100%">
|
|
<indexLine height="25vh" :chartData="logChartData"></indexLine>
|
|
</el-row>
|
|
<el-row>
|
|
<el-table :data="logTableData" height="50vh" style="width: 100%" @sort-change="handleSortChange">
|
|
<el-table-column prop="deviceName" label="设备名称" width="300"></el-table-column>
|
|
<el-table-column prop="sendCount" label="发送"></el-table-column>
|
|
<el-table-column prop="receiveCount" label="返回"></el-table-column>
|
|
<el-table-column prop="lossCount" label="丢失"></el-table-column>
|
|
<el-table-column prop="deviceStatus" label="状态">
|
|
<template slot-scope="scope">
|
|
<el-tag type="success" size="small" v-if="scope.row.deviceStatus=='1'">可达</el-tag>
|
|
<el-tag type="danger" size="small" v-else>不可达</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column prop="lossRate" label="丢包率"></el-table-column>
|
|
<el-table-column prop="rttAvg" label="平均时延"></el-table-column>
|
|
<el-table-column prop="networkQuality" label="网络质量">
|
|
<template slot-scope="scope">
|
|
<el-tag type="success" size="small" v-if="scope.row.networkQuality=='优'">优</el-tag>
|
|
<el-tag type="primary" size="small" v-if="scope.row.networkQuality=='良'">良</el-tag>
|
|
<el-tag type="warning" size="small" v-if="scope.row.networkQuality=='一般'">一般</el-tag>
|
|
<el-tag type="danger" size="small" v-if="scope.row.networkQuality=='差'">差</el-tag>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column width="200" prop="monitorTime" label="检测时间"></el-table-column>
|
|
|
|
</el-table>
|
|
<!-- <pagination
|
|
v-show="logTotal>0"
|
|
:total="logTotal"
|
|
:page.sync="logQueryParams.pageNum"
|
|
:limit.sync="logQueryParams.pageSize"
|
|
@pagination="networkLogTable"
|
|
/>-->
|
|
</el-row>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import {formatDate,addOrSubtractDays,getDaysRange} from "@/utils/dateUtils";
|
|
import TypeTree from "@/views/deviceManage/typeTree";
|
|
import LineChart from "@/views/deviceManage/lineChart";
|
|
import indexLine from "@/views/deviceManage/deviceOnline/indexLine";
|
|
import {deviceOnlineTable,deviceOnlineChart,networkLogTable,networkLogEcharts} from "@/api/deviceManage/deviceOnline";
|
|
import {typeTree,direction, useState, deviceState} from "@/enum/deviceEnum";
|
|
export default {
|
|
name: "index",
|
|
components: { TypeTree, LineChart, indexLine},
|
|
data() {
|
|
return {
|
|
chartData:{
|
|
xData:[],
|
|
yData:[]
|
|
},
|
|
tableData:[],
|
|
// 总条数
|
|
total: 0,
|
|
// 设备方向
|
|
directionOptions: direction,
|
|
// 使用状态
|
|
useStateOptions: useState,
|
|
// 设备状态
|
|
deviceStateOptions: deviceState,
|
|
logVisible:false,
|
|
deviceType:typeTree,
|
|
dateRange:[],
|
|
// 查询参数
|
|
queryParams: {
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
type:'',
|
|
orderByField:'online_rate',
|
|
orderDirection:'desc',
|
|
searchValue:'',
|
|
startTime:'2024-07-01 00:00:00',
|
|
time:'2024-07-24 00:00:00',
|
|
direction:''
|
|
},
|
|
logQueryParams: {
|
|
//pageNum: 1,
|
|
//pageSize: 10,
|
|
queryDate:new Date(),
|
|
deviceId:'',
|
|
},
|
|
logChartData:{},
|
|
logTableData:[],
|
|
logTotal:0
|
|
}
|
|
},
|
|
|
|
created() {
|
|
let rangeDate = getDaysRange(-30);
|
|
this.dateRange[0] = rangeDate.start;
|
|
this.dateRange[1] = rangeDate.end;
|
|
},
|
|
methods: {
|
|
defaultCheck(types){
|
|
this.queryParams.type = types.join(',');
|
|
this.deviceOnlineTable();
|
|
this.deviceOnlineChart();
|
|
},
|
|
nodeCheck(data, checked){
|
|
this.queryParams.type = checked.checkedKeys.join(',');
|
|
this.deviceOnlineTable();
|
|
this.deviceOnlineChart();
|
|
},
|
|
deviceOnlineTable(){
|
|
deviceOnlineTable(this.queryParams).then(response => {
|
|
this.tableData = response.rows;
|
|
this.total = response.total;
|
|
})
|
|
},
|
|
formatDate(isoString) {
|
|
const date = new Date(isoString);
|
|
const year = date.getFullYear();
|
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
const day = String(date.getDate()).padStart(2, '0');
|
|
const hours = String(date.getHours()).padStart(2, '0');
|
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
},
|
|
deviceOnlineChart(){
|
|
if(this.dateRange.length > 0){
|
|
this.queryParams.startTime = this.dateRange[0];
|
|
this.queryParams.time = this.dateRange[1];
|
|
deviceOnlineChart(this.queryParams).then(response => {
|
|
console.log("*******************************")
|
|
let data = response.data;
|
|
let xData = [], yData = [];
|
|
|
|
if (Object.keys(data).length !== 0) {
|
|
// 初始化 xData
|
|
Object.keys(data[Object.keys(data)[0]]).forEach(date => {
|
|
Object.keys(data[Object.keys(data)[0]][date]).forEach(time => {
|
|
const formattedTime = this.formatDate(time)
|
|
console.log("***************************")
|
|
console.log(formattedTime)
|
|
if (!xData.includes(formattedTime )) {
|
|
|
|
xData.push(formattedTime );
|
|
}
|
|
});
|
|
});
|
|
|
|
// 遍历外层的分类
|
|
for (const type in data) {
|
|
let yItem = {
|
|
name: this.findType(type).label,
|
|
unit: '%',
|
|
data: []
|
|
};
|
|
|
|
// 遍历该分类下的日期
|
|
for (const date in data[type]) {
|
|
// 遍历每个日期下的时间点
|
|
for (const time in data[type][date]) {
|
|
yItem.data.push(parseFloat(data[type][date][time].replace('%', '')));
|
|
}
|
|
}
|
|
|
|
yData.push(yItem);
|
|
}
|
|
|
|
// 对 xData 进行排序
|
|
/*
|
|
xData.sort((a, b) => moment(a).diff(moment(b)));
|
|
*/
|
|
|
|
this.chartData.xData = xData;
|
|
this.chartData.yData = yData;
|
|
}
|
|
})
|
|
}
|
|
|
|
},
|
|
seeLog(deviceId){
|
|
this.logVisible = true;
|
|
this.logQueryParams.queryDate=formatDate(new Date(),'yyyy-MM-dd');
|
|
this.logQueryParams.deviceId = deviceId;
|
|
this.logQuery();
|
|
},
|
|
networkLogEcharts(){
|
|
networkLogEcharts(this.logQueryParams).then(response => {
|
|
this.logChartData = response.data;
|
|
})
|
|
},
|
|
networkLogTable(){
|
|
networkLogTable(this.logQueryParams).then(response => {
|
|
this.logTableData = response.rows;
|
|
this.logTotal = response.total;
|
|
})
|
|
},
|
|
/** 重置按钮操作 */
|
|
resetQuery() {
|
|
this.resetForm("queryForm");
|
|
this.deviceOnlineTable();
|
|
},
|
|
handleSortChange({ prop, order }){
|
|
this.queryParams.orderDirection = order === 'ascending'?'asc':'desc';
|
|
if (prop === 'onlineRate') {
|
|
this.queryParams.orderByField = 'online_rate';
|
|
}
|
|
this.deviceOnlineTable();
|
|
},
|
|
logQuery(){
|
|
if(!this.logQueryParams.queryDate) return;
|
|
this.networkLogEcharts()
|
|
this.networkLogTable()
|
|
},
|
|
upDay(){
|
|
this.logQueryParams.queryDate = addOrSubtractDays(this.logQueryParams.queryDate, -1);
|
|
this.logQuery();
|
|
},
|
|
downDay(){
|
|
this.logQueryParams.queryDate = addOrSubtractDays(this.logQueryParams.queryDate, 1);
|
|
this.logQuery();
|
|
},
|
|
findType(typeCode) {
|
|
return this.deviceType.find(item => item.value == typeCode)
|
|
},
|
|
handleExport() {
|
|
this.download('system/status/export', {
|
|
...this.queryParams
|
|
}, `设备在线率${new Date().getTime()}.xlsx`)
|
|
},
|
|
handleRangePickerChange(){
|
|
if(this.dateRange.length > 0){
|
|
this.queryParams.startTime = this.dateRange[0];
|
|
this.queryParams.time = this.dateRange[1];
|
|
this.deviceOnlineChart();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
|
|
</style>
|
|
|