477 lines
14 KiB
Vue
477 lines
14 KiB
Vue
<template>
|
|
<div>
|
|
<!--监测点数据完整性 -->
|
|
<TableHeader
|
|
:showReset="false"
|
|
ref="TableHeaderRef"
|
|
@selectChange="selectChange"
|
|
datePicker
|
|
v-if="fullscreen"
|
|
></TableHeader>
|
|
<div
|
|
class="monitoringPoints"
|
|
:style="{
|
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`,
|
|
overflow: 'auto'
|
|
}"
|
|
v-loading="tableStore.table.loading"
|
|
>
|
|
<div style="flex: 1">
|
|
<div class="title">终端统计</div>
|
|
<div
|
|
class="box1"
|
|
:style="{
|
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px - 30px )`,
|
|
overflow: 'auto'
|
|
}"
|
|
>
|
|
<div class="statistics">
|
|
<div class="divBox div1">
|
|
<span class="iconfont icon-qiyezongshu" style="color: #57bc6e"></span>
|
|
<span class="divBox_title">终端总数</span>
|
|
<span class="divBox_num text-style" style="color: #57bc6e">
|
|
{{ statisticsList.allNum }}
|
|
</span>
|
|
</div>
|
|
<div class="divBox div2">
|
|
<span class="iconfont icon-zaiyunshebei" style="color: #67c23a"></span>
|
|
<span class="divBox_title">在运终端数</span>
|
|
<span class="divBox_num text-style" style="color: #67c23a">
|
|
{{ statisticsList.runNum }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="statistics">
|
|
<div class="divBox div3">
|
|
<span
|
|
class="iconfont icon-yichanglei_14feizhinengbiaozaiyunyichang"
|
|
style="color: #ffbf00"
|
|
></span>
|
|
<span class="divBox_title">调试终端数</span>
|
|
<span class="divBox_num text-style" style="color: #ffbf00">
|
|
{{ statisticsList.checkNum }}
|
|
</span>
|
|
</div>
|
|
<div class="divBox div4">
|
|
<span class="iconfont icon-tingyunshijianguanli" style="color: #f56c6c"></span>
|
|
<span class="divBox_title">停运终端数</span>
|
|
<span class="divBox_num text-style" style="color: #f56c6c">
|
|
{{ statisticsList.stopRunNum }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div style="flex: 2" class="ml15">
|
|
<div class="title">终端运行统计</div>
|
|
|
|
<div class="mb5" style="height: 40px">
|
|
<el-segmented
|
|
style="height: 100%"
|
|
v-model="segmented"
|
|
:props="props"
|
|
:options="segmentedList"
|
|
block
|
|
@change="tableStore.index()"
|
|
></el-segmented>
|
|
</div>
|
|
<div class="header">
|
|
<span style="width: 110px; text-align: left">
|
|
{{
|
|
segmented == 'Power_Network'
|
|
? '区域'
|
|
: segmented == 'Manufacturer'
|
|
? '终端厂家'
|
|
: '电网标志'
|
|
}}
|
|
</span>
|
|
<span style="width: 90px">终端总数</span>
|
|
<span style="flex: 1">完整性(%)</span>
|
|
<span style="flex: 1">在线率(%)</span>
|
|
<span style="flex: 1">异常率(%)</span>
|
|
</div>
|
|
<div
|
|
:style="{
|
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px - 105px )`,
|
|
overflow: 'auto'
|
|
}"
|
|
>
|
|
<div v-for="o in abnormal" class="abnormal mb10">
|
|
<span style="width: 110px; height: 24px" class="iconDiv">
|
|
<div :style="{ backgroundColor: o.citTotalOnlineRate < 90 ? '#FF9100' : '' }"></div>
|
|
{{ o.name }}
|
|
</span>
|
|
<!-- 终端总数 -->
|
|
<span style="width: 90px; color: #388e3c" class="text">
|
|
{{ o.count }}
|
|
</span>
|
|
<!-- -->
|
|
<sp
|
|
style="flex: 1; color: #388e3c"
|
|
class="text"
|
|
:class="` ${o.integrity < 90 ? 'text-red' : ''}`"
|
|
>
|
|
{{ o.integrity }}
|
|
</sp>
|
|
<span
|
|
style="flex: 1; color: #388e3c"
|
|
:class="` ${o.online < 90 ? 'text-red' : ''}`"
|
|
class="text"
|
|
>
|
|
{{ o.online }}
|
|
</span>
|
|
<span
|
|
style="flex: 1; color: #388e3c"
|
|
:class="` ${o.qualified > 10 ? 'text-red' : ''}`"
|
|
class="text"
|
|
>
|
|
{{ o.qualified }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script setup lang="ts">
|
|
import { ref, onMounted, provide, reactive, watch, nextTick } from 'vue'
|
|
import TableStore from '@/utils/tableStore'
|
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
|
import TableHeader from '@/components/table/header/index.vue'
|
|
import { useRoute } from 'vue-router'
|
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
|
import { useDictData } from '@/stores/dictData'
|
|
const dictData = useDictData()
|
|
const prop = defineProps({
|
|
w: { type: [String, Number] },
|
|
h: { type: [String, Number] },
|
|
width: { type: [String, Number] },
|
|
height: { type: [String, Number] },
|
|
timeKey: { type: [String, Number] },
|
|
timeValue: { type: Object }
|
|
})
|
|
|
|
const headerHeight = ref(57)
|
|
|
|
const TableHeaderRef = ref()
|
|
|
|
const monitoringPoints = ref({
|
|
runNum: 0,
|
|
abnormalNum: 0,
|
|
totalOnlineRate: 0
|
|
})
|
|
const segmented = ref('Power_Network')
|
|
const percentage = ref({})
|
|
const segmentedList = dictData.getBasicData('Statistical_Type', ['Report_Type', 'Voltage_Level', 'Load_Type'])
|
|
const props = {
|
|
value: 'code',
|
|
label: 'name'
|
|
}
|
|
const statisticsList: any = ref({
|
|
allNum: 0,
|
|
runNum: 0,
|
|
checkNum: 0,
|
|
stopRunNum: 0
|
|
})
|
|
const abnormal: any = ref([])
|
|
|
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
|
headerHeight.value = height
|
|
}
|
|
const totalData = ref([])
|
|
// 计算是否全屏展示
|
|
const fullscreen = computed(() => {
|
|
const w = Number(prop.w)
|
|
const h = Number(prop.h)
|
|
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
|
// 执行相应逻辑
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
})
|
|
|
|
const tableStore: any = new TableStore({
|
|
url: '/device-boot/deviceRunEvaluate/getRunEvaluateInfo',
|
|
method: 'POST',
|
|
|
|
showPage: false,
|
|
|
|
column: [],
|
|
|
|
beforeSearchFun: () => {
|
|
if (prop.timeValue && Array.isArray(prop.timeValue)) {
|
|
tableStore.table.params.searchBeginTime = prop.timeValue[0]
|
|
tableStore.table.params.searchEndTime = prop.timeValue[1]
|
|
}
|
|
tableStore.table.params.statisticalType = segmentedList.filter(item => item.code === segmented.value)[0]
|
|
},
|
|
|
|
loadCallback: () => {
|
|
totalData.value = Array.from(
|
|
tableStore.table.data
|
|
.map((item: any) => item.list)
|
|
.flat()
|
|
.reduce((map: any, item: any) => {
|
|
if (!map.has(item.id)) {
|
|
map.set(item.id, item)
|
|
}
|
|
return map
|
|
}, new Map())
|
|
.values()
|
|
)
|
|
|
|
// tableStore.table.data
|
|
statisticsList.value.allNum = totalData.value.length
|
|
statisticsList.value.runNum = totalData.value.filter(item => item.runFlag === '运行').length
|
|
statisticsList.value.checkNum = totalData.value.filter(item => item.runFlag === '调试').length
|
|
statisticsList.value.stopRunNum = totalData.value.filter(item => item.runFlag === '停运').length
|
|
|
|
abnormal.value = tableStore.table.data.filter((k: any) => {
|
|
if (tableStore.table.params.statisticalType.name == '终端厂家') {
|
|
return k.count != 0
|
|
} else {
|
|
return k.name != '上送国网' && k.name != '非上送国网'
|
|
}
|
|
})
|
|
}
|
|
})
|
|
tableStore.table.params.deptIndex = dictData.state.area[0].id
|
|
tableStore.table.params.lineRunFlag = 0
|
|
provide('tableStore', tableStore)
|
|
|
|
onMounted(() => {
|
|
tableStore.index()
|
|
})
|
|
watch(
|
|
() => prop.timeKey,
|
|
val => {
|
|
tableStore.index()
|
|
}
|
|
)
|
|
watch(
|
|
() => prop.timeValue,
|
|
|
|
val => {
|
|
tableStore.index()
|
|
},
|
|
|
|
{
|
|
deep: true
|
|
}
|
|
)
|
|
</script>
|
|
<style lang="scss" scoped>
|
|
@import '@/assets/font/iconfont.css';
|
|
.monitoringPoints {
|
|
display: flex;
|
|
}
|
|
.detail {
|
|
flex: 1;
|
|
}
|
|
.abnormal {
|
|
width: 100%;
|
|
background-color: #f3f6f9;
|
|
border-radius: 5px;
|
|
display: flex;
|
|
// justify-content: space-between;
|
|
align-items: center;
|
|
padding: 5px 0px 5px 10px;
|
|
.iconDiv {
|
|
display: flex;
|
|
align-items: center;
|
|
div {
|
|
width: 4px;
|
|
height: 18px;
|
|
margin-right: 5px;
|
|
background-color: var(--el-color-primary);
|
|
}
|
|
}
|
|
.text {
|
|
font-weight: 700;
|
|
font-size: 16px;
|
|
font-family: 'Source Code Pro', monospace;
|
|
text-align: center;
|
|
|
|
// font-feature-settings: 'tnum';
|
|
}
|
|
}
|
|
.header {
|
|
display: flex;
|
|
text-align: center;
|
|
|
|
font-weight: 700;
|
|
padding: 5px;
|
|
}
|
|
:deep(.el-card__header) {
|
|
padding: 10px;
|
|
span {
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
:deep(.el-card__body) {
|
|
padding: 10px;
|
|
}
|
|
.iconFont {
|
|
font-size: 18px;
|
|
display: inline-block;
|
|
vertical-align: middle;
|
|
}
|
|
.form {
|
|
position: relative;
|
|
.form_but {
|
|
position: absolute;
|
|
right: -22px;
|
|
}
|
|
}
|
|
.card-header {
|
|
font-size: 16px;
|
|
}
|
|
:deep(.table_name) {
|
|
color: var(--el-color-primary);
|
|
cursor: pointer;
|
|
text-underline-offset: 4px;
|
|
}
|
|
.echartTitle {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
|
|
div:nth-child(2) {
|
|
font-size: 16px;
|
|
color: #ff6600;
|
|
}
|
|
}
|
|
.title {
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
padding: 0 5px 5px;
|
|
}
|
|
|
|
:deep(.el-segmented__item-selected, ) {
|
|
clip-path: polygon(10% 0, 100% 0, 90% 100%, 0 100%);
|
|
}
|
|
:deep(.el-segmented__item, ) {
|
|
clip-path: polygon(10% 0, 100% 0, 90% 100%, 0 100%);
|
|
position: relative;
|
|
}
|
|
:deep(.el-segmented) {
|
|
clip-path: polygon(4% 0, 100% 0, 96% 100%, 0 100%);
|
|
}
|
|
.text-red {
|
|
color: #ff9100 !important;
|
|
}
|
|
|
|
.segmentedIcon {
|
|
position: absolute;
|
|
top: 1px;
|
|
left: 100px;
|
|
height: 18px !important;
|
|
line-height: 19px;
|
|
padding: 0 4px;
|
|
font-size: 12px;
|
|
background: #ff9100;
|
|
color: #fff;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.hexagon {
|
|
position: relative;
|
|
width: 100px;
|
|
height: 55px;
|
|
background-color: #19a094;
|
|
margin: 50px auto;
|
|
&::before {
|
|
border-bottom: 27.5px solid #19a094;
|
|
}
|
|
&::after {
|
|
border-top: 27.5px solid #19a094;
|
|
}
|
|
}
|
|
|
|
.hexagon::before,
|
|
.hexagon::after {
|
|
content: '';
|
|
position: absolute;
|
|
width: 0;
|
|
border-left: 50px solid transparent;
|
|
border-right: 50px solid transparent;
|
|
}
|
|
|
|
.hexagon::before {
|
|
bottom: 98%;
|
|
}
|
|
|
|
.hexagon::after {
|
|
top: 98%;
|
|
}
|
|
.hexagon1 {
|
|
background-color: #2e8b57;
|
|
&::before {
|
|
border-bottom: 27.5px solid #2e8b57;
|
|
}
|
|
&::after {
|
|
border-top: 27.5px solid #2e8b57;
|
|
}
|
|
}
|
|
.hexagon2 {
|
|
background-color: #ffbf00;
|
|
&::before {
|
|
border-bottom: 27.5px solid #ffbf00;
|
|
}
|
|
&::after {
|
|
border-top: 27.5px solid #ffbf00;
|
|
}
|
|
}
|
|
.hexagon3 {
|
|
background-color: #a52a2a;
|
|
&::before {
|
|
border-bottom: 27.5px solid #a52a2a;
|
|
}
|
|
&::after {
|
|
border-top: 27.5px solid #a52a2a;
|
|
}
|
|
}
|
|
.statistics {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
.divBox {
|
|
width: 100%;
|
|
height: 70px;
|
|
padding: 10px;
|
|
display: flex;
|
|
margin-bottom: 10px;
|
|
.iconfont {
|
|
font-size: 40px;
|
|
margin-right: 5px;
|
|
}
|
|
.divBox_title {
|
|
font-weight: 550;
|
|
}
|
|
.divBox_num {
|
|
font-size: 20px;
|
|
font-weight: 550;
|
|
margin-left: auto;
|
|
font-family: AlimamaDongFangDaKai;
|
|
}
|
|
align-items: center;
|
|
// text-align: center;
|
|
border-radius: 5px;
|
|
}
|
|
.div1 {
|
|
background-color: #eef8f0;
|
|
}
|
|
.div2 {
|
|
background-color: #67c23a24;
|
|
}
|
|
.div3 {
|
|
background-color: #ffbf0024;
|
|
}
|
|
.div4 {
|
|
background-color: #f56c6c24;
|
|
}
|
|
}
|
|
</style>
|