Files
admin-sjzx/src/components/cockpit/terminalEvaluation/index1.vue
2025-11-28 16:27:52 +08:00

451 lines
11 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 style="height: 135px" class="box1">
<div class="boxDiv hexagon">
<div style="color: #fff">100</div>
<div class="mt10 divBot">总数</div>
</div>
<div class="boxDiv hexagon hexagon1">
<div style="color: #fff">50</div>
<div class="mt10 divBot">在运</div>
</div>
</div>
<div style="height: 135px" class="box1">
<div class="boxDiv hexagon hexagon2">
<div style="color: #fff">25</div>
<div class="mt10 divBot">检修</div>
</div>
<div class="boxDiv hexagon hexagon3">
<div style="color: #fff">25</div>
<div class="mt10 divBot">停运</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" :options="segmentedList" block>
<template #default="scope">
<div>
<div>{{ typeof scope.item === 'object' ? scope.item.label : scope.item }}</div>
</div>
</template>
</el-segmented>
</div>
<div class="header">
<span style="width: 110px; text-align: left">
{{ segmented == 0 ? '区域' : segmented == 1 ? '终端厂家' : '电网标志' }}
</span>
<span style="flex: 1">在运终端数</span>
<span style="width: 80px">评价</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.integrity < 90 ? '#FF9100' : '' }"></div>
{{ o.targetName }}
</span>
<!-- 在运终端数 -->
<span style="flex: 1; color: #388e3c" class="text">
{{ o.rangeDesc }}
</span>
<span
style="width: 80px; color: #388e3c"
:class="` ${o.integrity < 90 ? 'text-red' : ''}`"
class="text"
>
{{ o.integrity }}
</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: 110,
abnormalNum: 10
})
const segmented = ref(0)
const percentage = ref({})
const segmentedList = ref([
{
label: '区域',
value: 0,
num: 0
},
{
label: '终端厂家',
value: 1,
num: 0
},
{
label: '电网标志',
value: 2,
num: 0
}
])
const abnormal: any = ref([
{
targetName: '唐山',
rangeDesc: 21,
length: 21,
integrity: '优秀'
},
{
targetName: '唐山',
rangeDesc: 21,
length: 21,
integrity: '优秀'
},
{
targetName: '唐山',
rangeDesc: 21,
length: 21,
integrity: '优秀'
},
{
targetName: '唐山',
rangeDesc: 21,
length: 21,
integrity: '优秀'
},
{
targetName: '唐山',
rangeDesc: 21,
length: 21,
integrity: '优秀'
},
{
targetName: '唐山',
rangeDesc: 21,
length: 21,
integrity: '优秀'
},
{
targetName: '唐山',
rangeDesc: 21,
length: 21,
integrity: '优秀'
},
{
targetName: '唐山',
rangeDesc: 21,
length: 21,
integrity: '优秀'
},
{
targetName: '唐山',
rangeDesc: 21,
length: 21,
integrity: 92
}
])
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
headerHeight.value = height
}
// 计算是否全屏展示
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 value = ref(new Date())
const list = ref()
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]
}
},
loadCallback: () => {
list.value = tableStore.table.data
}
})
tableStore.table.params.deptId = dictData.state.area[0].id
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>
.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;
}
.box1 {
display: flex;
align-items: center;
justify-content: space-around;
.boxDiv {
// flex: 1;
display: flex;
flex-direction: column;
align-items: center;
position: relative;
margin: 0 5px;
div:nth-child(1) {
position: absolute;
font-size: 30px;
top: -10px;
font-weight: 700;
}
.divBot {
font-size: 16px;
position: absolute;
top: 20px;
}
color: #fff;
}
}
.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;
}
}
</style>