Files
admin-sjzx/src/views/pqs/runManage/runEvaluate/index.vue
2025-05-13 15:26:24 +08:00

480 lines
17 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="default-main" style="position: relative">
<TableHeader date-picker>
<template v-slot:select>
<el-form-item label="电网侧标识">
<el-select
v-model="tableStore.table.params.powerFlag"
clearable
style="width: 100%"
placeholder="请选择电网侧标识"
>
<el-option
v-for="item in powerFlagList"
:key="item.id"
:label="item.name"
:value="item.algoDescribe"
></el-option>
</el-select>
</el-form-item>
</template>
<template v-slot:operation>
<el-button
type="primary"
class="ml10"
@click="toggle"
:icon="leftVisible ? 'el-icon-Hide' : 'el-icon-View'"
>
{{ leftVisible ? '隐藏' : '显示' }}
</el-button>
<el-tooltip placement="left-start">
<InfoFilled style="height: 20px" class="ml10" />
<!-- <el-button circle icon="el-icon-InfoFilled" /> -->
<template #content>
<div style="font-size: 16px" class="mt10 mb10">
<div>终端在线率</div>
<div class="em1">定义终端在指定时间段内处于在线状态的时间比例</div>
<div class="em1">计算方法在线率=终端在线时间/总监测时间×100%</div>
<div class="em1">评价标准</div>
<div class="em2">
<span style="color: #00b07d">优秀</span>
 在线率 95%
</div>
<div class="em2">
<span style="color: #2b7fd3">良好</span>
 90% 在线率 < 95
</div>
<div class="em2">
<span style="color: #ffcc33">一般</span>
 80% 在线率 < 90%
</div>
<div class="em2">
<span style="color: #97017e">较差</span>
 在线率 < 80%
</div>
<div class="mt10">数据完整性</div>
<div class="em1">定义终端上传数据的完整性和连续性</div>
<div class="em1">计算方法数据完整性=实际上传数据量/预期上传数据量×100%</div>
<div class="em1">评价标准</div>
<div class="em2">
<span style="color: #00b07d">优秀</span>
 完整性 98%
</div>
<div class="em2">
<span style="color: #2b7fd3">良好</span>
 95% 完整性 < 98%
</div>
<div class="em2">
<span style="color: #ffcc33">一般</span>
 90% 完整性 < 95%
</div>
<div class="em2">
<span style="color: #97017e">较差</span>
 完整性 < 90%
</div>
<div class="mt10">数据合格率</div>
<div class="em1">定义终端上传数据的合格率(以谐波电压为代表)</div>
<div class="em1">计算方法合格率=合格数据量/总数据量×100%</div>
<div class="em1">评价标准</div>
<div class="em2">
<span style="color: #00b07d">优秀</span>
 完整性 98%
</div>
<div class="em2">
<span style="color: #2b7fd3">良好</span>
 95% 完整性 < 98%
</div>
<div class="em2">
<span style="color: #ffcc33">一般</span>
 90% 完整性 < 95%
</div>
<div class="em2">
<span style="color: #97017e">较差</span>
 完整性 < 90%
</div>
<div class="mt10">综合评价方法</div>
<div class="em1">权重分配:根据各维度的重要性分配不同的权重例如:</div>
<div class="em2">终端在线率:20%</div>
<div class="em2">数据完整性:50%</div>
<div class="em2">数据合格率:30%</div>
<div class="em1">综合评分:综合评分=(单项评分x权重)</div>
<div class="em1">评价等级:</div>
<div class="em2">
<span style="color: #00b07d">优秀</span>
 综合评分 90
</div>
<div class="em2">
<span style="color: #2b7fd3">良好</span>
 80 综合评分 < 90
</div>
<div class="em2">
<span style="color: #ffcc33">一般</span>
 70 综合评分 < 80
</div>
<div class="em2">
<span style="color: #97017e">较差</span>
 综合评分 < 70
</div>
</div>
</template>
</el-tooltip>
</template>
</TableHeader>
<div class="mapBox">
<el-form :inline="true" class="demo-form-inline">
<el-form-item>
<Area
ref="areaRef"
@change-value="changeValue"
:show-all-levels="false"
v-model="tableStore.table.params.deptIndex"
style="width: 100px"
/>
</el-form-item>
</el-form>
</div>
<Map />
<transition name="slide-left">
<div class="left" :style="height" v-if="leftVisible">
<BorderBox13
style="height: 200px"
:color="[color[0], color[0]]"
class="box"
:backgroundColor="`#f3f1ec90`"
title="终端统计"
>
<div class="title">
<span class="iconfont icon-zhongduantongji-xian"></span>
终端统计
<!-- <el-button link class="view" icon="el-icon-View" @click="endpointStatistics">详情</el-button> -->
</div>
<statistics :params="tableStore.table.data" />
</BorderBox13>
<BorderBox13
:color="[color[0], color[0]]"
class="box"
style="flex: 1"
:backgroundColor="`#f3f1ec90`"
title="终端运行评价"
>
<div class="title">
<span class="iconfont icon-daipingjia"></span>
终端运行评价
<!-- <el-button link class="view" icon="el-icon-View" @click="endpointStatistics">详情</el-button> -->
</div>
<run :params="tableStore.table.params" ref="runRef" @reviewDetails="reviewDetails" />
</BorderBox13>
<BorderBox13
:style="height3"
:color="[color[0], color[0]]"
class="box"
:backgroundColor="`#f3f1ec90`"
title="终端运行评价详情"
>
<div class="title">
<span class="iconfont icon-a-qushi1"></span>
终端运行评价详情
<!-- <el-button link class="view" icon="el-icon-View">详情</el-button> -->
</div>
<terminalOperation :params="tableStore.table.params" ref="terminalOperationRef" />
</BorderBox13>
</div>
</transition>
<transition name="slide-right">
<div class="right" :style="height" v-if="rightVisible">
<BorderBox13
:color="[color[0], color[0]]"
class="box box-2"
:backgroundColor="`#f3f1ec90`"
title="区域终端运行评价"
>
<div class="title">
<span class="iconfont icon-a-ziyuan118"></span>
区域终端运行评价
<el-button link class="view" icon="el-icon-View" @click="regionEvaluation">详情</el-button>
</div>
<region />
</BorderBox13>
<div :style="height3">
<BorderBox13
style="height: 100%"
:color="[color[0], color[0]]"
class="box"
:backgroundColor="`#f3f1ec90`"
title="最近一周终端评价趋势"
>
<div class="title">
<span class="iconfont icon-yunhangxiangqing"></span>
最近一周终端评价趋势
</div>
<week ref="weekRef" :params="tableStore.table.params"/>
</BorderBox13>
</div>
</div>
</transition>
<transition name="slide-bottom">
<div class="center" :style="height3" v-if="centerVisible">
<BorderBox13
:color="[color[0], color[0]]"
class="box"
:backgroundColor="`#f3f1ec90`"
title="异常终端详情"
>
<div class="title">
<span class="iconfont icon-yichangxiangqing-xian"></span>
异常终端详情
</div>
<terminalDetails ref="terminalDetailsRef" :params="tableStore.table.params" />
<table />
</BorderBox13>
</div>
</transition>
<!-- 终端统计弹框 -->
<statisticsPopUpBox ref="statisticsPopUpBoxRef" />
<!-- 区域详情 -->
<regionDetails ref="regionDetailsRef" />
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, provide } from 'vue'
import TableHeader from '@/components/table/header/index.vue'
import TableStore from '@/utils/tableStore'
import { useDictData } from '@/stores/dictData'
import { mainHeight } from '@/utils/layout'
import Area from '@/components/form/area/index.vue'
import Map from './components/map.vue'
import { BorderBox13 } from '@kjgl77/datav-vue3'
import { useConfig } from '@/stores/config'
import terminalOperation from './components/terminalOperation.vue'
import region from './components/region.vue'
import { InfoFilled } from '@element-plus/icons-vue'
import week from './components/week.vue'
import terminalDetails from './components/terminalDetails.vue'
import statistics from './components/statistics.vue'
import run from './components/run.vue'
import statisticsPopUpBox from './components/statisticsPopUpBox.vue'
import regionDetails from './components/regionDetails.vue'
defineOptions({
name: 'runManage/runEvaluate'
})
const runRef = ref()
const weekRef = ref()
const terminalDetailsRef = ref()
const config = useConfig()
const color = config.layout.elementUiPrimary
const dictData = useDictData()
const height = mainHeight(115)
const height3 = mainHeight(115, 3)
const classificationData = dictData.getBasicData('Statistical_Type', ['Report_Type'])
//字典获取监督对象类型
const powerFlagList = dictData.getBasicData('power_flag')
const tableStore = new TableStore({
url: '/device-boot/dev/statisticDevNum',
method: 'POST',
column: [],
loadCallback: () => {
runRef.value.info()
weekRef.value.info()
terminalDetailsRef.value.info()
}
})
tableStore.table.params.deptIndex = dictData.state.area[0].id
tableStore.table.params.loadType = dictData.getBasicData('Interference_Source')
tableStore.table.params.terminaloption = dictData.getBasicData('Dev_Manufacturers')
tableStore.table.params.scale = dictData.getBasicData('Dev_Voltage_Stand')
tableStore.table.params.statisticalType = classificationData.filter(item => item.name == '电网拓扑')[0] //dictData.getBasicData('Statistical_Type', ['Report_Type'])[0]
tableStore.table.params.monitorFlag = 2
tableStore.table.params.powerFlag = 2
tableStore.table.params.serverName = 'harmonicBoot'
provide('tableStore', tableStore)
const leftVisible = ref(true)
const rightVisible = ref(true)
const centerVisible = ref(true)
const statisticsPopUpBoxRef = ref(true)
const regionDetailsRef = ref(true)
const toggle = () => {
leftVisible.value = !leftVisible.value
rightVisible.value = !rightVisible.value
centerVisible.value = !centerVisible.value
}
// 区域变化
const changeValue = (val: any) => {
tableStore.index()
}
// 区域详情
const regionEvaluation = () => {
regionDetailsRef.value.open()
}
const terminalOperationRef = ref()
//渲染 在线率
const reviewDetails = (item: any) => {
terminalOperationRef.value.info(item)
}
onMounted(() => {
// 加载数据
tableStore.index()
})
</script>
<style lang="scss" scoped>
.left,
.right {
display: flex;
position: absolute;
top: 80px;
width: 450px;
flex-direction: column;
z-index: 99;
transition: all 0.3s ease;
}
.left {
left: 15px;
}
.right {
right: 15px !important;
.box {
flex: 1; /* 占2份高度 */
}
.box-2 {
flex: 2; /* 占2份高度 */
}
}
.box {
padding: 20px 10px 10px;
}
.center {
position: absolute;
bottom: 16px;
left: 50%;
transform: translateX(-50%);
width: calc(100% - 950px);
min-width: 480px;
.box {
flex: 1; /* 占2份高度 */
padding: 20px 10px 10px;
}
transition: all 0.3s ease;
}
.title {
// padding: 5px 5px 5px 10px;
background: linear-gradient(to right, var(--el-color-primary), #ffffff00);
font-size: 16px;
// font-weight: bold;
color: #fff;
display: flex;
align-items: center;
.iconfont {
font-size: 22px;
margin: 0 5px 0 10px;
}
button {
margin-left: auto;
margin-right: 10px;
}
}
.toggle-btn {
position: absolute;
z-index: 100;
padding: 5px 10px;
cursor: pointer;
}
.slide-left-enter-active,
.slide-left-leave-active {
transition: all 0.3s ease;
}
.slide-left-enter-from,
.slide-left-leave-to {
transform: translateX(-100%);
opacity: 0;
}
.slide-right-enter-active,
.slide-right-leave-active {
transition: all 0.3s ease;
}
.slide-right-enter-from,
.slide-right-leave-to {
transform: translateX(100%);
opacity: 0;
}
.slide-bottom-enter-active,
.slide-bottom-leave-active {
transition: all 0.3s ease;
}
.slide-bottom-enter-from,
.slide-bottom-leave-to {
transform: translateY(100%);
opacity: 0;
}
.em1 {
margin-top: 5px;
text-indent: 1em;
}
.em2 {
margin-top: 5px;
text-indent: 2em;
}
:deep(.title > .el-button.is-link) {
color: #fff;
&:hover {
color: #ccc;
}
}
:deep(.mapBox) {
position: absolute;
top: 80px;
left: calc(50% + 45px);
z-index: 10;
.el-select {
min-width: 100px;
.el-select__wrapper {
height: 46px !important;
border-radius: 8px;
}
}
.Icon {
height: 46px;
width: 46px;
background-color: #fff;
border-radius: 8px;
text-align: center;
line-height: 50px;
cursor: pointer;
.fa-refresh {
color: var(--el-color-primary) !important;
}
}
.el-input__wrapper {
height: 46px;
border-radius: 8px;
}
.el-form-item {
margin-right: 15px;
}
}
:deep(.view) {
color: #000 !important;
}
</style>