<template>
|
<div class="device">
|
<div class="device-l">
|
<div class="left">
|
<div class="left-item">
|
<div class="item-t">设备时长</div>
|
<div class="item-c">
|
<el-table
|
:data="facityWarnTable"
|
:header-cell-style="headerStyle"
|
:cell-style="rowStyle"
|
style="height: 100%;"
|
>
|
<el-table-column prop="pointName" label="异常监测点" />
|
<el-table-column prop="facilityName" label="异常设备" />
|
<el-table-column prop="description" label="报警内容" />
|
<el-table-column prop="alarmTime" label="报警时长" />
|
</el-table>
|
</div>
|
</div>
|
<div class="left-item">
|
<div class="item-t">
|
<div class="title-left">风机管理</div>
|
<div class="title-right">
|
<el-select
|
v-model="typeValue.fengji"
|
size="small"
|
style="width: 8rem"
|
@change="getFanList"
|
>
|
<el-option
|
v-for="item in fengjiOption"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
<el-button type="success" size="small">一键启动</el-button>
|
</div>
|
</div>
|
<div class="item-c">
|
<div class="fengji">
|
<div class="fengjiItem" v-for="(item, index) in fengjiList" :key="index">
|
<div class="fengji-title">{{ item.pointName }}</div>
|
<div class="fengji-status">
|
<img :class="{run: item.facilityFanState === 1}" src="@/assets/images/screen/fengji.png" alt="" />
|
<span v-if="item.facilityFanState === 0">停止</span>
|
<span v-else-if="item.facilityFanState === 1">运行中</span>
|
<span v-else-if="item.facilityFanState === 2">一级报警</span>
|
<span v-else-if="item.facilityFanState === 3">二级报警</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="left-item">
|
<div class="item-t">工单处理</div>
|
<div class="item-c">
|
<el-table
|
:data="ordertable"
|
:header-cell-style="headerStyle"
|
:cell-style="rowStyle"
|
style="height: 100%;"
|
>
|
<el-table-column prop="code" label="工单号" />
|
<el-table-column prop="typeView" label="工单类型" />
|
<el-table-column prop="createTimeView" label="上报时间" />
|
<el-table-column prop="createUserName" label="上报人" />
|
<el-table-column prop="address" label="所属地址" />
|
<el-table-column label="工单状态">
|
<template #default="scoped">
|
<div v-if="scoped.row.executeState === 200" style="color: #36fc0e;">已处理</div>
|
<div v-else style="color: #ccc;">未处理</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
<div class="left-item">
|
<div class="item-t">设备状态</div>
|
<div class="item-c">
|
<div ref="statusRef" class="sbStatus"></div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="device-c">
|
<div class="center">
|
<div class="center-item">
|
<div class="item-t">
|
<div class="title-left">实时数据</div>
|
<div class="title-right">
|
<el-select
|
v-model="typeValue.pointId"
|
size="small"
|
style="width: 8rem"
|
@change="getNewData"
|
>
|
<el-option
|
v-for="item in pointList"
|
:key="item.id"
|
:label="item.pointName"
|
:value="item.id"
|
/>
|
</el-select>
|
<el-select
|
v-model="typeValue.facilityState"
|
size="small"
|
style="width: 8rem"
|
@change="getNewData"
|
>
|
<el-option
|
v-for="item in fengjiOption"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</div>
|
</div>
|
<div class="item-c">
|
<div class="data-list">
|
<template v-for="(item, index) in newDataList" :key="index">
|
<dataItem :item="item" />
|
</template>
|
</div>
|
</div>
|
</div>
|
<div class="center-item">
|
<div class="item-t">终端监控分类曲线</div>
|
<div class="item-c">
|
<div ref="moniterRef" class="moniter"></div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="device-r">
|
<div class="right">
|
<div class="right-item">
|
<div class="item-t">风机状态</div>
|
<div class="item-c">
|
<el-table
|
:data="fengjiStatusTable"
|
:header-cell-style="headerStyle"
|
:cell-style="rowStyle"
|
style="height: 100%;"
|
>
|
<el-table-column prop="facilityId" label="风机编号" />
|
<el-table-column prop="runTimeString" label="单次运行时长" />
|
<el-table-column prop="pointName" label="运行地址" />
|
<el-table-column prop="sumTimeString" label="总运行时长" />
|
</el-table>
|
</div>
|
</div>
|
<div class="right-item">
|
<div class="item-t">设备报警</div>
|
<div class="item-c">
|
<el-table
|
:data="warnRecordTable"
|
:header-cell-style="headerStyle"
|
:cell-style="rowStyle"
|
style="height: 100%;"
|
>
|
<el-table-column prop="facilityCode" label="设备编号" />
|
<el-table-column prop="alarmTypeView" label="报警类型" />
|
<el-table-column prop="address" label="报警地址" />
|
<el-table-column prop="latestAlarmTime" label="报警时间" />
|
</el-table>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { onMounted, reactive } from 'vue';
|
import dataItem from './components/dataItem.vue'
|
import * as echarts from 'echarts';
|
import { getOrder, getFanFacity, getFacityData, getFacityRunTime, getFacityWarn, getFacityStatus, getPointStatic } from '@/api/screen/device'
|
import { getWarnRecord } from '@/api/screen/data'
|
import pointApi from "@/api/facility/point";
|
|
const facityWarnTable = ref([])
|
const fengjiList = ref([])
|
const ordertable = ref([])
|
const facityStatus = ref([])
|
const newDataList = ref([])
|
const lineChartList = ref([])
|
const fengjiStatusTable = ref([])
|
const warnRecordTable = ref([])
|
|
const typeValue = reactive({
|
fengji: 1,
|
pointId: '',
|
facilityState: 1,
|
})
|
const fengjiOption = [
|
{label: '停止', value: 0},
|
{label: '运行中', value: 1},
|
{label: '一级报警', value: 2},
|
{label: '二级报警', value: 3}
|
]
|
const pointList = ref([])
|
|
const headerStyle = {
|
"background-color": '#041025 !important'
|
}
|
const rowStyle = {
|
"background-color": '#081C3F !important'
|
}
|
|
const statusRef = ref()
|
const moniterRef = ref()
|
let statusCharts = null
|
let moniterCharts = null
|
|
const setStatusCharts = () => {
|
const option = {
|
tooltip: {
|
trigger: 'item'
|
},
|
series: [
|
{
|
type: 'pie',
|
radius: ['40%', '70%'],
|
data: facityStatus.value
|
}
|
]
|
};
|
|
statusCharts.setOption(option)
|
}
|
|
const setMoniterCharts = () => {
|
let xdata = []
|
let sdata = []
|
lineChartList.value.forEach(el => {
|
xdata.push(el.pointName)
|
sdata.push(el.count)
|
})
|
const option = {
|
tooltip: {
|
trigger: 'axis'
|
},
|
dataZoom: [
|
{
|
id: 'dataZoomX',
|
type: 'slider',
|
xAxisIndex: [0],
|
filterMode: 'filter'
|
}
|
],
|
xAxis: {
|
type: 'category',
|
boundaryGap: false,
|
data: xdata
|
},
|
yAxis: {
|
type: 'value'
|
},
|
series: [
|
{
|
data: sdata,
|
type: 'line',
|
areaStyle: {
|
color: {
|
type: 'linear',
|
x: 0,
|
y: 0,
|
x2: 0,
|
y2: 1,
|
colorStops: [
|
{offset: 0, color: 'rgba(118,196,235,1)' },
|
{offset: 1, color: 'rgba(118,196,235,0)'}
|
],
|
}
|
}
|
}
|
]
|
};
|
|
moniterCharts.setOption(option)
|
}
|
|
// 获取监控点列表
|
const getPointData = () => {
|
const searchData = {
|
limit: 100,
|
page: 1
|
}
|
return pointApi().search(searchData).then((res) => {
|
pointList.value = res.data.list
|
typeValue.pointId = res.data.list[0].id
|
})
|
}
|
|
// 设备报警时长
|
const getFacityTimelong = () => {
|
getFacityWarn().then(res => {
|
facityWarnTable.value = res.data
|
})
|
}
|
|
// 获取工单
|
const getOrderList = () => {
|
getOrder().then(res => {
|
ordertable.value = res.data
|
})
|
}
|
|
// 风机管理
|
const getFanList = () => {
|
getFanFacity({ type: typeValue.fengji }).then(res => {
|
fengjiList.value = res.data
|
})
|
}
|
|
// 设备状态
|
const getStatus = () => {
|
getFacityStatus().then(res => {
|
facityStatus.value = res.data.map(item => {
|
return {
|
name: item.typeName,
|
value: Number(item.value)
|
}
|
})
|
setStatusCharts()
|
})
|
}
|
|
// 实时数据
|
const getNewData = () => {
|
const searchData = {
|
pointId: typeValue.pointId,
|
facilityState: typeValue.facilityState
|
}
|
getFacityData(searchData).then(res => {
|
newDataList.value = res.data
|
})
|
}
|
|
// 监控统计
|
const getPoint = () => {
|
getPointStatic().then(res => {
|
lineChartList.value = res.data
|
setMoniterCharts()
|
})
|
}
|
|
|
// 风机状态
|
const getFanStatus = () => {
|
getFacityRunTime().then(res => {
|
fengjiStatusTable.value = res.data
|
})
|
}
|
|
// 设备报警
|
const getFacityWarnRecord = () => {
|
getWarnRecord().then(res => {
|
warnRecordTable.value = res.data
|
})
|
}
|
|
const init = async () => {
|
if(statusRef.value){
|
statusCharts = echarts.init(statusRef.value)
|
}
|
if(moniterRef.value){
|
moniterCharts = echarts.init(moniterRef.value)
|
}
|
await getPointData()
|
getFacityTimelong()
|
getOrderList()
|
getFanList()
|
getStatus()
|
getNewData()
|
getPoint()
|
getFanStatus()
|
getFacityWarnRecord()
|
}
|
|
|
onMounted(() => {
|
init()
|
})
|
</script>
|
|
<style scoped lang="scss">
|
.device{
|
height: 100%;
|
color: #fff;
|
display: flex;
|
justify-content: space-between;
|
:deep(.el-table){
|
--el-table-border-color: #000;
|
--el-table-bg-color: transparent;
|
th{
|
font-size: 12px;
|
color: #fff;
|
}
|
tr{
|
font-size: 12px;
|
color: #fff;
|
}
|
.el-table__cell{
|
border: none;
|
}
|
}
|
&-l{
|
width: 29%;
|
height: 100%;
|
.left{
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
.left-item{
|
flex-shrink: 0;
|
width: 100%;
|
height: 24%;
|
background-image: url('@/assets/images/screen/ct-small.png');
|
background-size: 100% 100%;
|
background-repeat: no-repeat;
|
.item-t{
|
width: 100%;
|
height: 3rem;
|
line-height: 3rem;
|
padding: 0 5rem 0 4rem;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
.title-right{
|
display: flex;
|
gap: 1rem;
|
}
|
}
|
.item-c{
|
height: calc(100% - 3rem);
|
padding: 0.5rem;
|
// overflow-y: scroll;
|
// &::-webkit-scrollbar{
|
// display: none;
|
// }
|
.sbStatus{
|
width: 100%;
|
height: 100%;
|
}
|
}
|
.fengji{
|
width: 100%;
|
height: 100%;
|
display: flex;
|
flex-wrap: wrap;
|
overflow-y: scroll;
|
&::-webkit-scrollbar{
|
display: none;
|
}
|
.fengjiItem{
|
width: 50%;
|
height: 50%;
|
text-align: center;
|
.fengji-title{
|
font-size: 0.8rem;
|
padding: 0.5rem 0;
|
}
|
.fengji-status{
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
img{
|
width: 2rem;
|
height: 2rem;
|
margin-right: 2rem;
|
}
|
.run{
|
animation: rotateAnimation 1s linear 0s infinite;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
&-c{
|
width: 40%;
|
height: 100%;
|
.center{
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
.center-item{
|
height: 49%;
|
background-image: url('@/assets/images/screen/ct-large.png');
|
background-size: 100% 100%;
|
background-repeat: no-repeat;
|
.item-t{
|
height: 3rem;
|
line-height: 3rem;
|
padding: 0 6rem 0 3.8rem;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
.title-right{
|
display: flex;
|
gap: 1rem;
|
}
|
}
|
.item-c{
|
height: calc(100% - 3rem);
|
padding: 0.5rem;
|
.moniter{
|
width: 100%;
|
height: 100%;
|
}
|
.data-list{
|
height: 100%;
|
display: flex;
|
flex-wrap: wrap;
|
gap: 0.7rem;
|
overflow-y: scroll;
|
&::-webkit-scrollbar{
|
display: none;
|
}
|
}
|
}
|
}
|
}
|
}
|
&-r{
|
width: 29%;
|
height: 100%;
|
.right{
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
.right-item{
|
height: 49%;
|
background-image: url('@/assets/images/screen/ct-default.png');
|
background-size: 100% 100%;
|
background-repeat: no-repeat;
|
.item-t{
|
height: 3rem;
|
line-height: 3rem;
|
padding-left: 3rem;
|
}
|
.item-c{
|
height: calc(100% - 3rem);
|
padding: 0.5rem;
|
}
|
}
|
}
|
}
|
}
|
|
@keyframes rotateAnimation{
|
0%{
|
transform: rotate(0deg);
|
}
|
100%{
|
transform: rotate(360deg);
|
}
|
}
|
</style>
|