修改 终端运行评价

This commit is contained in:
GGJ
2025-05-21 10:12:46 +08:00
parent 2ef0f92743
commit 12f5d105fe
12 changed files with 364 additions and 135 deletions

View File

@@ -144,7 +144,7 @@
strokeColor="#0e8780"
:strokeOpacity="1"
:fillColor="item.background || ''"
:fillOpacity="0.5"
:fillOpacity="0.6"
></bm-polygon>
</div>
</div>
@@ -211,6 +211,12 @@ import { getAssessOverview } from '@/api/device-boot/panorama'
import { getRunEvaluate } from '@/api/device-boot/runEvaluate'
import { getGridDiagramAreaData } from '@/api/device-boot/panorama'
const emit = defineEmits(['changeValue', 'drop', 'show'])
const props = defineProps({
params: {
type: Object,
default: () => {}
}
})
import mapJson from '@/views/pqs/panorama/components/boundary'
const datePickerRef = ref()
const height = mainHeight(90)
@@ -219,8 +225,7 @@ const dictData = useDictData()
const inputQuery: any = ref('')
const QueryList: any = ref([])
const activeName: any = ref(0)
const zoomMap = ref(9.8)
const zoomMap = ref(8.9)
const colorKey = ref('')
const showCollapse: any = ref(true)
const showWrap: any = ref(false)
@@ -311,7 +316,7 @@ const polyline = ref<any>([])
const lineId = ref('')
const center = ref({
lng: 122.42588,
lat: 41.210977
lat: 40.810977
})
const infoWindowPoint = ref<anyObj>({
lng: 0,
@@ -323,7 +328,7 @@ const initMap = async ({ BMap, map }: any) => {}
// 加载点
const addMarkers = async (row?: any, key?: any, num?: any) => {
let params = {
deptIndex: deptIndex.value,
deptIndex: props.params.deptIndex,
monitorFlag: 2,
powerFlag: 2,
searchBeginTime: datePickerRef.value.timeValue[0],
@@ -487,7 +492,7 @@ const grids = (row: any) => {
AreaData.value = []
// 综合评估
getRunEvaluate({ ...row, deptIndex: deptIndex.value }).then((res: any) => {
getRunEvaluate({ ...row, deptIndex: props.params.deptIndex }).then((res: any) => {
console.log('🚀 ~ getRunEvaluate ~ res:', res)
AreaData.value = res.data
GridDiagramArea()
@@ -500,35 +505,19 @@ const radiusPop = (k: any) => {
}
const GridDiagramArea = () => {
boundaryList.value.forEach((item: any) => {
// assessList.value.forEach((y: any) => {
// if (item.orgName == y.name) {
// if (y.score == 3.14159) {
// } else if (y.score > 4.5) {
// item.background = '#33996699'
// } else if (y.score > 4) {
// item.background = '#3399ff99'
// } else if (y.score > 3) {
// item.background = '#ffcc3399'
// } else if (y.score > 2) {
// item.background = '#db088799'
// } else if (y.score > 0) {
// item.background = '#ff000099'
// }
// }
// })
AreaData.value.forEach((k: any, i: any) => {
if (item.orgName == k.name) {
for (let kk in item) {
k[kk] = item[kk]
}
if (k.evaluate >= 90) {
k.background = '#0fff04'
k.background = '#00b07d'
} else if (k.evaluate >= 80) {
k.background = '#2b7fd3'
} else if (k.evaluate >= 70) {
k.background = '#ffcc33'
k.background = '#ff8c00'
} else {
k.background = '#97017e'
k.background = '#c00'
}
}
})

View File

@@ -2,13 +2,16 @@
<div :style="height" style="overflow-y: auto" class="pd10">
<!-- <MyEChart :options="options" /> -->
<div v-for="(item, index) in List">
<div class="box">
<div class="div">{{ item.name }}({{ item.count }})</div>
<div class="box" @mouseenter="item.flag = false" @mouseleave="item.flag = true">
<div class="div">{{ item.name }} <span>({{ item.count }})</span></div>
<!-- <el-progress style="flex: 1" :percentage="(item.count / total).toFixed(2) * 100">
<span>{{ item.count }}</span>
</el-progress> -->
<el-progress style="flex: 1" :percentage="item.score" :color="ratingColor(item.score)">
<span :style="`color:${ratingColor(item.score)}`">{{ item.score }}</span>
<span v-if="item.flag" :style="`color:${ratingColor(item.score)}`">
{{ ratingName(item.score) }}
</span>
<span v-else :style="`color:${ratingColor(item.score)}`">{{ item.score }}</span>
</el-progress>
</div>
<el-divider />
@@ -35,6 +38,9 @@ const info = () => {
areaTerminalStatistic(props.params).then(res => {
total.value = res.data.reduce((sum, item) => sum + Number(item.count), 0)
List.value = res.data
List.value.forEach(item => {
item.flag = true
})
})
// let dataSource = [
// { value: '90', name: '张家口' },
@@ -95,7 +101,7 @@ const info = () => {
// ? '#2b7fd3'
// : params.value >= 70
// ? '#ffcc33'
// : '#97017e'
// : '#c00'
// }
// },
// markLine: {
@@ -148,13 +154,24 @@ const info = () => {
}
const ratingColor = (num: number) => {
if (num >= 90) {
return '#19A094'
return '#00b07d'
} else if (num >= 80) {
return '#2b7fd3'
} else if (num >= 70) {
return '#ff8c00'
} else {
return '#97017e'
return '#c00'
}
}
const ratingName = (num: number) => {
if (num >= 90) {
return '优秀'
} else if (num >= 80) {
return '良好'
} else if (num >= 70) {
return '一般'
} else {
return '较差'
}
}
onMounted(() => {
@@ -198,12 +215,17 @@ defineExpose({
}
}
.box {
cursor: pointer;
// display: flex;
.div {
// width: 100px;
font-size: 16px;
span{
font-size: 14px;
}
}
}
:deep(.el-divider--horizontal) {
margin: 10px 0;
margin: 5px 0;
}
</style>

View File

@@ -1,12 +1,22 @@
<template>
<div :style="height" style="overflow-y: auto">
<div>
<div class="btnsBox">
<el-radio-group v-model="radio2" @change="info">
<el-radio-button label="电压" value="Voltage_Level" />
<!-- <el-radio-group v-model="radio2" @change="info">
<el-radio-button label="电压" value="Voltage_Level" />
<el-radio-button label="厂家" value="Manufacturer" />
</el-radio-group>
</el-radio-group> -->
<el-segmented v-model="radio2" size="default" @change="info" :options="segmentedList" block>
<template #default="scope">
<div>{{ scope.item.label }}</div>
</template>
</el-segmented>
</div>
<div class="boxBG">
<div class="appraiseTop">
<div style="flex: 1" class="title">{{ radio2 == 'Voltage_Level' ? '电压等级' : '终端厂家' }}</div>
<div style="width: 150px">在运终端数</div>
<div style="width: 50px">评价</div>
</div>
<div class="boxBG" :style="height">
<div
class="appraise"
v-for="(item, i) in List"
@@ -15,9 +25,10 @@
>
<!-- <div class="iconfont icon-wanzhengshuaifenxi2"></div> -->
<div style="flex: 1">{{ item.name }}</div>
<div style="color: #0fff04; width: 150px">{{ Math.floor(item.evaluate * 100).toFixed(0) / 100 }}</div>
<div style="width: 40px" :style="`color:${ratingColor(item.evaluate)}`">
<div style="flex: 1" class="title">{{ item.name }}</div>
<!-- <div style="color: #0fff04; width: 150px">{{ Math.floor(item.evaluate * 100).toFixed(0) / 100 }}</div> -->
<div style="color: #0fff04; width: 150px">{{ item.devIds.length }}</div>
<div style="width: 50px" :style="`color:${ratingColor(item.evaluate)}`">
{{ rating(item.evaluate) }}
</div>
</div>
@@ -37,11 +48,21 @@ const props = defineProps({
default: () => {}
}
})
const segmentedList = ref([
{
label: '电压',
value: 'Voltage_Level'
},
{
label: '厂家',
value: 'Manufacturer'
}
])
const rowColor = ref(0)
const List: any = ref([])
const dictData = useDictData()
const radio2 = ref('Voltage_Level')
const height = mainHeight(520, 1.5)
const height = mainHeight(560, 1.5)
const timer: any = ref(null)
const classificationData = dictData.getBasicData('Statistical_Type', ['Report_Type'])
const info = () => {
@@ -79,13 +100,13 @@ const rating = (num: number) => {
}
const ratingColor = (num: number) => {
if (num >= 90) {
return '#0fff04'
return '#00b07d'
} else if (num >= 80) {
return '#2b7fd3'
} else if (num >= 70) {
return '#ff8c00'
} else {
return '#97017e'
return '#ff0000'
}
}
const clickRow = (item: any, i: number) => {
@@ -104,7 +125,8 @@ defineExpose({
.btnsBox {
position: absolute;
right: 5px;
top: 0px;
// right: 40%;
top: 1px;
}
// ::v-deep .el-radio-button__inner {
// padding: 8px 18px;
@@ -137,18 +159,23 @@ defineExpose({
.boxBG {
display: flex;
flex-direction: column;
// margin-top: 10px;
justify-content: space-around;
overflow: hidden;
overflow-y: auto;
width: 100%;
.appraise {
// height: 30px;
width: 99%;
background-image: url('@/assets/imgs/bg02.png');
width: 98%;
margin: 0 auto;
// background-image: url('@/assets/imgs/bg02.png');
// background-color: var(--el-color-primary);
background-color: var(--el-color-primary-light-3);
box-shadow: 2px 4px 4px 2px rgba(0, 0, 0, 0.5);
border-radius: 5px;
background-size: 100% 100%;
display: inline-block;
padding: 10px 30px 10px 10px;
margin-top: 10px;
padding: 8px 30px 8px 10px;
margin-bottom: 10px;
color: #fff;
display: flex;
// justify-content: space-around;
@@ -162,10 +189,8 @@ defineExpose({
}
.iconfont {
display: flex;
height: 60%;
aspect-ratio: 1 / 1;
background-color: var(--el-color-primary);
font-size: 24px;
justify-content: center;
@@ -174,8 +199,30 @@ defineExpose({
}
}
}
.appraiseTop {
width: 98%;
margin: 0 auto;
margin: 5px 0;
padding: 2px 30px 2px 10px;
font-size: 16px;
font-weight: 650;
display: flex;
div {
text-align: center;
}
}
.hoverBox {
background-color: var(--el-color-primary-light-5);
background-color: var(--el-color-primary) !important;
// background-image: none !important;
}
:deep(.el-segmented__item-selected, ) {
clip-path: polygon(20% 0, 100% 0, 80% 100%, 0 100%);
}
:deep(.el-segmented__item, ) {
clip-path: polygon(20% 0, 100% 0, 80% 100%, 0 100%);
position: relative;
}
:deep(.el-segmented) {
clip-path: polygon(10% 0, 100% 0, 90% 100%, 0 100%);
}
</style>

View File

@@ -1,23 +1,23 @@
<template>
<div style="height: 150px" class="box1">
<div class="boxDiv">
<div style="color: #07ccca">{{ props.params.allNum }}</div>
<img src="@/assets/imgs/ditu.png" />
<div style="height: 145px" class="box1">
<div class="boxDiv hexagon">
<div style="color: #fff">{{ props.params.allNum }}</div>
<!-- <div class="hexagon"></div> -->
<div class="mt10 divBot">总数</div>
</div>
<div class="boxDiv">
<div style="color: #339900">{{ props.params.runNum }}</div>
<img src="@/assets/imgs/ditu.png" />
<div class="boxDiv hexagon hexagon1">
<div style="color: #fff">{{ props.params.runNum }}</div>
<!-- <div class="hexagon"></div> -->
<div class="mt10 divBot">在运</div>
</div>
<div class="boxDiv">
<div style="color: #ffbf00">{{ props.params.checkNum }}</div>
<img src="@/assets/imgs/ditu.png" />
<div class="boxDiv hexagon hexagon2">
<div style="color: #fff">{{ props.params.checkNum }}</div>
<!-- <div class="hexagon"></div> -->
<div class="mt10 divBot">调试</div>
</div>
<div class="boxDiv">
<div style="color: #cc0000">{{ props.params.stopRunNum }}</div>
<img src="@/assets/imgs/ditu.png" />
<div class="boxDiv hexagon hexagon3">
<div style="color: #fff">{{ props.params.stopRunNum }}</div>
<!-- <div class="hexagon"></div> -->
<div class="mt10 divBot">停运</div>
</div>
</div>
@@ -49,22 +49,77 @@ onMounted(() => {
flex-direction: column;
align-items: center;
position: relative;
margin: 0 5px;
img {
width: 90%;
}
div:nth-child(1) {
position: absolute;
font-size: 30px;
top: -20px;
top: -10px;
font-weight: 700;
}
.divBot {
font-size: 16px;
position: absolute;
top: 10px;
top: 20px;
}
color: #fff;
}
}
.hexagon {
position: relative;
width: 100%;
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: 100%;
}
.hexagon::after {
top: 100%;
}
.hexagon1 {
background-color: #339900;
&::before {
border-bottom: 27.5px solid #339900;
}
&::after {
border-top: 27.5px solid #339900;
}
}
.hexagon2 {
background-color: #ffbf00;
&::before {
border-bottom: 27.5px solid #ffbf00;
}
&::after {
border-top: 27.5px solid #ffbf00;
}
}
.hexagon3 {
background-color: #cc0000;
&::before {
border-bottom: 27.5px solid #cc0000;
}
&::after {
border-top: 27.5px solid #cc0000;
}
}
</style>

View File

@@ -1,21 +1,31 @@
<template>
<div :style="height" class="mt10">
<div :style="height" class="mt10" style="position: relative">
<vxe-table height="auto" v-bind="defaultAttribute" :data="tableData">
<vxe-column type="seq" width="70px" title="序号"></vxe-column>
<vxe-column field="name" title="终端名称"></vxe-column>
<vxe-column field="subName" title="所属电站"></vxe-column>
<vxe-column field="name" title="终端名称" min-width="100"></vxe-column>
<vxe-column field="subName" title="所属电站" min-width="100"></vxe-column>
<vxe-column field="ip" title="网络参数" min-width="100"></vxe-column>
<vxe-colgroup title="运行评价">
<vxe-column field="integrityRate" title="完整率(%)"></vxe-column>
<vxe-column field="onLineRate" title="在线率(%)"></vxe-column>
<vxe-column field="passRate" title="合格率(%)"></vxe-column>
<vxe-column field="integrityRate" title="完整率(%)" min-width="90"></vxe-column>
<vxe-column field="onLineRate" title="在线率(%)" min-width="90"></vxe-column>
<vxe-column field="passRate" title="合格率(%)" min-width="90"></vxe-column>
</vxe-colgroup>
<vxe-column field="evaluate" title="评分(分)">
<vxe-column field="evaluate" title="评价" min-width="90">
<template v-slot="{ row }">
{{ Math.floor(row.evaluate * 100).toFixed(0) / 100 }}
<!-- {{ Math.floor(row.evaluate * 100).toFixed(0) / 100 }} -->
<span :style="`color:${ratingColor(row.evaluate)}`">
{{ ratingName(row.evaluate) }}
</span>
</template>
</vxe-column>
</vxe-table>
<div class="legeng">
<div v-for="item in legengList">
<span :style="`background-color: ${item.color};`"></span>
<span>{{ item.title }}</span>
</div>
</div>
</div>
</template>
<script setup lang="ts">
@@ -31,12 +41,51 @@ const props = defineProps({
})
const tableData = ref([])
const height = mainHeight(360, 3)
const legengList = [
{
color: '#00b07d',
title: '优秀'
},
{
color: '#2b7fd3',
title: '良好'
},
{
color: '#ff8c00',
title: '一般'
},
{
color: '#c00',
title: '较差'
}
]
const info = () => {
getRunEvaluateDetail({ ...props.params, ids: [] }).then(res => {
tableData.value = res.data.slice(0, 10)
})
}
const ratingColor = (num: number) => {
if (num >= 90) {
return '#00b07d'
} else if (num >= 80) {
return '#2b7fd3'
} else if (num >= 70) {
return '#ff8c00'
} else {
return '#c00'
}
}
const ratingName = (num: number) => {
if (num >= 90) {
return '优秀'
} else if (num >= 80) {
return '良好'
} else if (num >= 70) {
return '一般'
} else {
return '较差'
}
}
defineExpose({
info
})
@@ -83,4 +132,33 @@ defineExpose({
:dppe(.el-select__wrapper) {
width: 26px !important;
}
.legeng {
position: absolute;
padding: 5px;
top: -168px;
left: -7px;
width: 70px;
font-size: 12px;
height: 100px;
background: #fff;
border-radius: 5px;
display: grid;
line-height: 22px;
grid-template-rows: auto;
div {
display: flex;
align-items: center;
justify-content: center;
span:nth-child(1) {
display: inline-block;
height: 10px;
border-radius: 2px;
width: 15px;
margin-right: 5px;
}
}
}
</style>

View File

@@ -1,21 +1,32 @@
<template>
<div :style="height">
<el-select
class="selectBox"
v-model="value"
placeholder="请选择"
size="small"
value-key="id"
multiple
collapse-tags
collapse-tags-tooltip
:multiple-limit="6"
filterable
style="width: 130px"
@change="change"
>
<el-option v-for="item in List" :key="item.id" :label="item.name" :value="item" />
</el-select>
<!-- -->
<el-popover :visible="visible" placement="left" :width="220">
<el-select
v-model="value"
placeholder="请选择"
size="small"
value-key="id"
multiple
collapse-tags
collapse-tags-tooltip
:multiple-limit="6"
filterable
style="width: 130px"
>
<el-option v-for="item in List" :key="item.id" :label="item.name" :value="item" />
</el-select>
<div style="text-align: right" class="mt10">
<el-button size="small" text @click="visible = false">取消</el-button>
<el-button size="small" type="primary" @click="change">确定</el-button>
</div>
<template #reference>
<div class="selectBox" @click="visible = true">
<Tools style="width: 16px" />
</div>
<!-- <el-button>Delete</el-button> -->
</template>
</el-popover>
<MyEChart :options="options" />
</div>
</template>
@@ -25,12 +36,15 @@ import MyEChart from '@/components/echarts/MyEchart.vue'
import { mainHeight } from '@/utils/layout'
import { yMethod } from '@/utils/echartMethod'
import { lastWeekTrend } from '@/api/device-boot/runEvaluate'
import { Tools } from '@element-plus/icons-vue'
const props = defineProps({
params: {
type: Object,
default: () => {}
}
})
const visible = ref(false)
const value: any = ref([])
const List: any = ref([])
const options = ref({})
@@ -119,7 +133,8 @@ const change = () => {
data: item.score
})
})
console.log(123)
visible.value = false
}
onMounted(() => {})
defineExpose({
@@ -129,13 +144,22 @@ defineExpose({
<style lang="scss" scoped>
.selectBox {
position: absolute;
top: 1px;
top: 2px;
right: 10px;
clip-path: polygon(10% 0, 100% 0, 90% 100%, 0 100%);
width: 60px;
height: 28px;
display: flex;
line-height: 28px;
justify-content: center;
cursor: pointer;
background-color: var(--el-color-primary);
color: #fff;
}
:deep(.el-tag) {
max-width: 110px !important;
}
:deep(.el-select) {
min-width: 190px;
}
// :deep(.el-tag) {
// max-width: 110px !important;
// }
// :deep(.el-select) {
// min-width: 190px;
// }
</style>

View File

@@ -51,7 +51,7 @@
 80% 在线率 < 90%
</div>
<div class="em2">
<span style="color: #97017e">较差</span>
<span style="color: #c00">较差</span>
 在线率 < 80%
</div>
@@ -72,7 +72,7 @@
 90% 完整性 < 95%
</div>
<div class="em2">
<span style="color: #97017e">较差</span>
<span style="color: #c00">较差</span>
 完整性 < 90%
</div>
@@ -93,7 +93,7 @@
 90% 完整性 < 95%
</div>
<div class="em2">
<span style="color: #97017e">较差</span>
<span style="color: #c00">较差</span>
 完整性 < 90%
</div>
<div class="mt10">综合评价方法</div>
@@ -116,7 +116,7 @@
 70 综合评分 < 80
</div>
<div class="em2">
<span style="color: #97017e">较差</span>
<span style="color: #c00">较差</span>
 综合评分 < 70
</div>
</div>
@@ -139,7 +139,7 @@
</el-form>
</div>
<Map ref="mapRef" />
<Map ref="mapRef" :params="tableStore.table.params" />
<transition name="slide-left">
<div class="left" :style="height" v-if="leftVisible">
@@ -200,7 +200,10 @@
<div class="title">
<span class="iconfont icon-a-ziyuan118"></span>
区域终端运行评价
<el-button link class="view" icon="el-icon-View" @click="regionEvaluation">详情</el-button>
<!-- <div class="view" @click="regionEvaluation">
详情
<ArrowRight style="width: 12px" />
</div> -->
</div>
<region :params="tableStore.table.params" ref="regionRef" />
</BorderBox13>
@@ -253,6 +256,7 @@ import TableStore from '@/utils/tableStore'
import { useDictData } from '@/stores/dictData'
import { mainHeight } from '@/utils/layout'
import Area from '@/components/form/area/index.vue'
import { ArrowRight } from '@element-plus/icons-vue'
import Map from './components/map.vue'
import { BorderBox13 } from '@kjgl77/datav-vue3'
import { useConfig } from '@/stores/config'
@@ -378,6 +382,7 @@ onMounted(() => {
background: linear-gradient(to right, var(--el-color-primary), #ffffff00);
font-size: 16px;
// font-weight: bold;
height: 33px;
color: #fff;
display: flex;
align-items: center;
@@ -385,7 +390,8 @@ onMounted(() => {
font-size: 22px;
margin: 0 5px 0 10px;
}
button {
button,
.view {
margin-left: auto;
margin-right: 10px;
}
@@ -477,6 +483,14 @@ onMounted(() => {
}
}
:deep(.view) {
color: #000 !important;
clip-path: polygon(10% 0, 100% 0, 90% 100%, 0 100%);
width: 60px;
height: 28px;
display: flex;
font-size: 14px;
justify-content: center;
line-height: 28px;
cursor: pointer;
background-color: var(--el-color-primary);
}
</style>