You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

562 lines
16 KiB
Vue

1 year ago
<template>
<div class="app-container app-box">
<div class="app-left">
<div class="dept-tree">
<div class="dtree-head">按设备组查看</div>
<el-tree
ref="dept-tree"
:props="defaultProps"
:data="deviceGroupList"
class="filter-tree"
:expand-on-click-node="false"
highlight-current
default-expand-all
@node-click="groupNodeClick"
>
<span slot-scope="{ node, data }" class="custom-tree-node">
<i v-if="data.children.length<=0 && node.expanded" class="el-icon-tickets" />
<i v-else-if="data.children && node.expanded" class="el-icon-folder-opened" />
<i v-else class="el-icon-folder" />
<span class="fontSize14" :title="node.label || &quot;-&quot;">{{ node.label }}</span>
</span>
</el-tree>
<div class="dtree-head" style="margin-top:30px;cursor:pointer">按传感器类型查看</div>
<ul class="sensorlist">
<li v-for="(item) in sensorData" :key="item.id" @click="sensorNodeClick(item.id)">
<svg-icon :icon-class="item.icon" class-name="shuiwei" style="font-size:18px" />{{ item.name }}
</li>
</ul>
</div>
</div>
<div class="app-right">
<div class="table-top">
<el-button size="mini" type="info" plain @click="tableExpend">{{ expendName }}</el-button>
<el-button size="mini" type="warning" plain @click="dispAllDev"></el-button>
<el-button size="mini" type="success" plain @click="tableExpend">线</el-button>
<el-button size="mini" type="danger" plain @click="tableExpend">线</el-button>
<div class="devmsg"> {{ totalNum }} 个智慧杆设备离线 {{ offlineNum }} 在线 {{ onlineNum }} 预警 {{ yujinNum }} </div>
</div>
<div class="app-r-table">
<el-table
v-if="refreshtable"
ref="userLevel"
:data="tableData"
style="margin-bottom: 20px;width: 100%;"
height="calc(100vh - 220px)"
row-key="id"
:row-style="{height: '0'}"
:header-cell-style="{ background: '#f8f8f8', color: '#333', padding: '8px' }"
:header-row-style="{padding:'0px'}"
:cell-style="{ padding: '8px' }"
:show-header="false"
:default-expand-all="expendAll"
:tree-props="{children: 'sensors', hasChildren: 'hasChildren'}"
:row-class-name="tableRowClassName"
class="tableClass"
>
<el-table-column prop="devname" label="设备名">
<template slot-scope="scope">
<svg-icon
v-if="!scope.row.sensors"
:icon-class="reIcoValue(scope.row.type)"
class-name="shuiwei"
:style="connectStyle(scope.row.linkStatus,scope.row.redWarning,scope.row.yellowWarning,scope.row.orangeWarning)"
/>
<span v-if="!scope.row.sensors" class="devicename" :style="connectStyle(scope.row.linkStatus,scope.row.redWarning,scope.row.yellowWarning,scope.row.orangeWarning)">{{
scope.row.name }}</span>
<span v-if="scope.row.sensors" class="devicename">{{ scope.row.name }}<span style="color:cornflowerblue">{{ scope.row.linkStatus == 1 ? '' : '线' }}</span></span>
<!-- <span v-if="scope.row.imei" class="devicename">IMEI:{{ scope.row.imei }}</span> -->
<!-- <span v-if="scope.row.address" class="devicename" style="font-weight:normal;font-size: 14px;">{{ scope.row.address }}</span> -->
</template>
</el-table-column>
<el-table-column prop="status" label="设备状态">
<template slot-scope="scope">
<span v-if="scope.row.imei" class="devicename">IMEI:{{ scope.row.imei }}</span>
<span v-if="!scope.row.sensors" :style="connectStyle(scope.row.linkStatus,scope.row.redWarning,scope.row.yellowWarning,scope.row.orangeWarning)">
{{ scope.row.linkStatus == 1 ? '已连接' : '未连接' }}
<span class="sport">端口{{ scope.row.devPort }}</span>
<div class="updatetime">更新{{ scope.row.lastUpdateTime }}</div>
</span>
</template>
</el-table-column>
<el-table-column prop="currentValue" label="设备值">
<template slot-scope="scope">
<span class="valuestyle" :style="connectStyle(scope.row.linkStatus,scope.row.redWarning,scope.row.yellowWarning,scope.row.orangeWarning)">{{ scope.row.currentValue }} {{
scope.row.unitName }}
<span v-if="scope.row.type ==3">{{ reFengxiang(scope.row.currentValue ) }}</span>
<span v-if="!scope.row.sensors" class="warnstyle" title="已达到预警值,请及时处理">
<svg-icon
icon-class="jinggao"
class-name="jinggao"
:style="reWarn(scope.row.linkStatus,scope.row.redWarning,scope.row.yellowWarning,scope.row.orangeWarning)"
/></span>
</span>
</template>
</el-table-column>
<el-table-column label="操作项">
<template slot-scope="scope">
<span
v-if="!scope.row.sensors"
class="historydata"
:style="connectStyle(scope.row.linkStatus)"
@click="showlog(scope.row.id,scope.row.name)"
><i class="el-icon-s-data" /> 历史数据</span>
</template>
</el-table-column>
</el-table>
</div>
<pagination
v-show="total > 0"
:total="total"
:page-size.sync="listQuery.PageSize"
:page-no.sync="listQuery.PageNo"
@pagination="getList"
/>
</div>
<el-dialog
v-el-drag-dialog
:title="dialogFromTitle"
:visible.sync="showLogDailog"
:close-on-click-modal="false"
width="80%"
>
<linechart :chart-data="lineChartData" />
</el-dialog>
</div>
</template>
<script>
import { getDeviceList, getDevReport } from '@/api/device'
import { getDeviceGroupList } from '@/api/devgroup'
import { getSensorLog, getSensorTypeList } from '@/api/sensor'
import elDragDialog from '@/directive/el-drag-dialog'
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
import linechart from './components/LineChart'
const lineChartData = {
newVisitis: {
expectedData: [],
titleData: [],
actualData: []
}
}
export default {
name: 'Monitor',
components: { Pagination, linechart },
directives: { elDragDialog },
data() {
return {
refreshtable: true,
expendAll: true,
lineChartData: lineChartData.newVisitis,
activeNames: ['1'],
deviceGroupList: [],
defaultProps: { label: 'name', children: 'children' },
dialogFromTitle: '',
tableData: [],
listLoading: true,
listQuery: {
PageNo: 1,
PageSize: 10,
name: '',
GroupCode: -1,
type: ''
},
total: 0,
timer: null, // 定时器名称
logData: [],
showLogDailog: false,
timerLogSensor: {
id: '',
name: ''
},
sensorList: [],
sensorData: [],
currenSensorId: -1,
expendName: '收起列表',
onlineNum: '',
offlineNum: '',
totalNum: '',
yujinNum: ''
}
},
mounted() {
this.getDevReportInfo()
this.getList()
this.getSensorList()
this.get_DeviceGroupList()
this.timer = setInterval(() => {
if (this.showLogDailog === true && this.timerLogSensor.id !== '') {
setTimeout(this.showlog(this.timerLogSensor.id, this.timerLogSensor.name), 0)
}
if (this.currenSensorId !== -1) {
setTimeout(this.getSensorDataList, 0)
} else {
setTimeout(this.getList, 0)
}
}, 1000 * 10)
},
beforeDestroy() {
clearInterval(this.timer)
this.timer = null
},
methods: {
dispAllDev() {
this.listQuery.GroupCode = -1
this.listQuery.type = ''
this.currenSensorId = -1
this.getSensorList()
this.get_DeviceGroupList()
this.getList()
},
tableExpend() {
this.refreshtable = false
this.expendAll = !this.expendAll
if (this.expendAll === false) {
this.expendName = '展开列表'
} else {
this.expendName = '收起列表'
}
this.$nextTick(() => {
this.refreshtable = true
})
},
sensorNodeClick(sensorId) {
this.currenSensorId = sensorId
this.getSensorDataList(sensorId)
},
async getDevReportInfo() {
await getDevReport().then(response => {
this.totalNum = response['data']['数量']
this.onlineNum = response['data']['在线数量']
this.offlineNum = response['data']['离线数量']
this.yujinNum = response['data']['预警数量']
})
},
async getSensorDataList() {
const { PageNo, PageSize } = this.listQuery
await getDeviceList({ PageNo, PageSize, SensorType: this.currenSensorId }).then(response => {
this.total = response.data.total
this.tableData = response.data.items
this.listLoading = false
}).catch(() => {
this.listLoading = false
})
},
async groupNodeClick(obj, node, self) {
this.currenSensorId = -1
this.listQuery.GroupCode = obj.id === '0' || obj.id === 0 ? -1 : obj.id
this.listLoading = true
const { PageNo, PageSize, GroupCode } = this.listQuery
await getDeviceList({ PageNo, PageSize, GroupCode }).then(response => {
this.total = response.data.total
this.tableData = response.data.items
this.listLoading = false
}).catch(() => {
this.listLoading = false
})
},
async get_DeviceGroupList() {
this.listLoading = true
await getDeviceGroupList({ PageNo: 1, PageSize: 10000 }).then(response => {
const list1 = []
const list2 = []
const rData = response.data.items
console.log('rData', rData.length)
for (let index = 0; index < rData.length; index++) {
const childrens = rData[index].children
for (let n = 0; n < childrens.length; n++) {
childrens[n].name = childrens[n].name + '(' + childrens[n].count + ')'
}
list2[index] = { id: rData[index].id, name: rData[index].name + '(' + rData[index].count + ')', children: childrens }
}
list1[0] = { id: '0', name: '所有分组', children: list2 }
this.deviceGroupList = list1
}).catch(() => {
this.listLoading = false
})
},
refresh() {
this.timer = setTimeout(async() => {
await this.getList()
}, 5000) // 设置五秒后刷新
},
getList() {
this.listLoading = true
getDeviceList(this.listQuery).then(response => {
this.tableData = response.data.items
this.total = response.data.total
this.listLoading = false
})
},
tableRowClassName(row, rowIndex) {
if (row.row.sensors) {
return 'warning-row'
}
},
handleChange(val) {
console.log(val)
},
reWarn(cn, red = false, yellow = false, orange = false) {
if (cn !== 1) return { display: 'none' }
if (red === true && cn === 1) {
return {
color: 'red',
fontWeight: 'bold'
}
}
if (yellow === true && cn === 1) {
return {
color: 'yellow',
fontWeight: 'bold'
}
}
if (orange === true && cn === 1) {
return {
color: 'orange',
fontWeight: 'bold'
}
}
return { display: 'none' }
},
connectStyle(cn, red = false, yellow = false, orange = false) {
if (cn !== 1) {
return {
color: 'rgb(187 186 186)',
fontWeight: 'bold'
}
} else {
if (red === true) {
return {
color: 'red',
fontWeight: 'bold'
}
} else if (yellow === true) {
return {
color: 'yellow',
fontWeight: 'bold'
}
} else if (orange === true) {
return {
color: 'orange',
fontWeight: 'bold'
}
} else {
return ''
}
}
},
showlog(id, name) {
const logQuery = { id: id }
this.timerLogSensor.id = id
this.timerLogSensor.name = name
getSensorLog(logQuery).then(response => {
this.logData = response.data.items
const rData = response.data.items
const tData = []
const vData = []
for (let index = 0; index < rData.length; index++) {
const cIndex = rData.length - 1 - index
tData[index] = rData[cIndex]['recTime']
vData[index] = rData[cIndex]['currentValue']
}
this.lineChartData.titleData = tData
this.lineChartData.expectedData = vData
this.dialogFromTitle = name + '的历史数据'
this.showLogDailog = true
})
},
getSensorList() {
getSensorTypeList().then(response => {
const rData = response.data
this.sensorData = rData
const tempData = {}
rData.forEach(element => {
tempData[element['id']] = element.icon
})
this.sensorList = tempData
})
},
reIcoValue(itype) {
const icon = this.sensorList[itype]
return icon || ''
},
reFengxiang(du) {
const aDu = parseInt(du)
let x = ''
switch (true) {
case aDu >= 0 && aDu <= 22:
x = '北风'
break
case aDu >= 338 && aDu <= 360:
x = '北风'
break
case aDu >= 23 && aDu <= 67:
x = '东北风'
break
case aDu >= 68 && aDu <= 111:
x = '东风'
break
case aDu >= 112 && aDu <= 157:
x = '东南风'
break
case aDu >= 158 && aDu <= 201:
x = '南风'
break
case aDu >= 202 && aDu <= 247:
x = '西南风'
break
case aDu >= 248 && aDu <= 290:
x = '西风'
break
case aDu >= 291 && aDu <= 337:
x = '西北风'
break
default:
x = ''
}
return x
}
}
}
</script>
<style lang="scss" >
.warnstyle{
font-size: 18px;
color:#666;
font-weight: normal;
margin-left: 5px;
}
.app-box {
display: flex;
}
.app-left {
width: 300px;
padding: 10px;
background: #fff;
height: calc(100vh - 100px);
}
.app-right {
width: calc(100vw - 415px);
margin-left: 15px;
padding: 15px;
background: #fff;
height: calc(100vh - 100px);
}
.dept-tree {
width: 100%;
}
.valuestyle {
font-size: 20px;
color: rgb(12, 184, 12);
font-weight: bold;
}
.el-table .warning-row {
background: rgb(246, 249, 252) !important;
font-weight: bold;
}
.dtree-head {
background: #409EFF;
color: #fff;
font-size: 14px;
padding: 8px 0px 8px 0px;
text-align: center;
margin-bottom: 12px;
cursor: pointer;
}
.dtree-head:hover {
background: #0881fa
}
.shuiwei {
color: #8e7eff;
font-size: 22px;
margin-right: 10px;
}
.devicename {
font-weight: bold;
}
.valuemaxstyle {
color: red;
}
.queryhistory {
cursor: pointer;
color: #087df3
}
.noconnect {
color: #ccc
}
.historydata {
color: #b10606;
cursor: pointer;
}
.sensorlist,
.sensorlist li {
list-style: none;
padding: 0px;
margin: 0px;
}
.sensorlist {
width: 90%;
padding-left: 10%
}
.sensorlist li {
padding: 8px 0px 0px 0px;
cursor: pointer;
color: #606266;
font-size: 14px;
}
.sensorlist li:hover {
color: #087df3;
}
.sensorlist li svg-icon {
font-size: 12px;
}
.fontSize14 {
font-size: 14px;
}
.sport {
font-size: 12px;
font-weight: normal;
}
.updatetime {
font-size: 12px;
font-weight: normal;
}
.table-top{padding: 0px 0px 5px 0px; width: 100%; display: flex;}
.devmsg{line-height: 30px;margin-left:20px;color:#076ace;font-size:14px}
</style>>