调整电网一张图污染水平评估

This commit is contained in:
guanj
2026-07-20 10:04:02 +08:00
parent e77c57f8d0
commit 5eb5a01b50
6 changed files with 357 additions and 383 deletions

View File

@@ -109,19 +109,19 @@
<template #content> <template #content>
<div class="thd-limit-tip__row"> <div class="thd-limit-tip__row">
<span>U < 6kV</span> <span>U < 6kV</span>
<span>5.0</span> <span>5.0%</span>
</div> </div>
<div class="thd-limit-tip__row"> <div class="thd-limit-tip__row">
<span>6kV U 20kV</span> <span>6kV U 20kV</span>
<span>4.0</span> <span>4.0%</span>
</div> </div>
<div class="thd-limit-tip__row"> <div class="thd-limit-tip__row">
<span>35kV U 66kV</span> <span>35kV U 66kV</span>
<span>3.0</span> <span>3.0%</span>
</div> </div>
<div class="thd-limit-tip__row"> <div class="thd-limit-tip__row">
<span>110kV U 1000kV</span> <span>110kV U 1000kV</span>
<span>2.0</span> <span>2.0%</span>
</div> </div>
</template> </template>
<el-icon><WarningFilled /></el-icon> <el-icon><WarningFilled /></el-icon>

View File

@@ -1,299 +1,260 @@
<template> <template>
<!-- 综合评估详情 --> <!-- 综合评估详情 -->
<el-dialog draggable title="综合评估统计" v-model="dialogVisible" width="1400px"> <el-dialog draggable title="稳态电能质量水平评估" v-model="dialogVisible" width="1400px">
<div> <div class="title mb5">
<vxe-table v-bind="defaultAttribute" ref="vxeRef" height="300px" :data="tableData"> <span>区域污染水平评估</span>
<vxe-column field="deptName" title="地市" /> </div>
<vxe-column field="assessLevel" title="综合评估结论"> <div style="display: flex">
<template #default="scope"> <div style="width: 400px">
<!-- class="conclusion" <vxe-table
:class=" v-bind="defaultAttribute"
scope.row.assessLevel == '特质' ref="tableRef"
? 'background1' @cell-click="currentChangeEvent"
: scope.row.assessLevel == '较差' height="250px"
? 'background2' :row-config="{ isCurrent: true, isHover: true }"
: scope.row.assessLevel == '极差' :data="tableData"
? 'background3' style="cursor: pointer"
: '' >
" --> <vxe-column field="deptName" title="地市" />
<span> <vxe-column field="score" title="污染值" sortable>
{{ scope.row.assessData }} <template #default="scope">
</span> <span
</template> :style="{
</vxe-column> color: setColor(scope.row.score)
<vxe-column field="qualifyData" title="指标合格率(%)" /> }"
>
<!-- <vxe-colgroup title="评估结论"> {{ scope.row.score }}
<vxe-column field="vdevAssessLevel" title="电压偏差"> </span>
<template #default="scope"> </template>
<span </vxe-column>
class="conclusion" </vxe-table>
:class=" </div>
scope.row.vdevAssessLevel == '特质' <div class="ml10 " style="width: 980px">
? 'background1' <vxe-table
: scope.row.vdevAssessLevel == '较差' v-bind="defaultAttribute"
? 'background2' @cell-click="clickAttribute"
: scope.row.vdevAssessLevel == '极差' v-loading="loadingTab"
? 'background3' ref="vxeRef"
: '' height="250px"
" :data="subdata"
> style="cursor: pointer"
{{ scope.row.vdevAssessLevel }} >
</span> <vxe-column type="seq" width="70" title="序号"></vxe-column>
</template> <vxe-column field="subName" title="变电站名称" min-width="120"></vxe-column>
</vxe-column> <vxe-column field="lineName" title="监测点名称" align="center" min-width="120"></vxe-column>
<vxe-column field="objName" title="监测对象名称" align="center" min-width="100"></vxe-column>
<vxe-column field="freqAssessLevel" title="频率偏差"> <vxe-column field="loadType" title="干扰源类型" align="center" min-width="100"></vxe-column>
<template #default="scope"> <vxe-column field="powerFlag" title="监测位置" align="center" min-width="100"></vxe-column>
<span <vxe-column field="vharmonicValue" title="污染值" sortable min-width="80">
class="conclusion" <template #default="scope">
:class=" <span
scope.row.freqAssessLevel == '特质' :style="{
? 'background1' color: setColor(scope.row.vharmonicValue)
: scope.row.freqAssessLevel == '较差' }"
? 'background2' >
: scope.row.freqAssessLevel == '极差' {{ scope.row.vharmonicValue }}
? 'background3' </span>
: '' </template>
" </vxe-column>
> </vxe-table>
{{ scope.row.freqAssessLevel }} </div>
</span> </div>
</template> <div class="title mb5 mt10">
</vxe-column> <span>敏感及重要用户评估</span>
</div>
<vxe-column field="harmAssessLevel" title="电压总谐波畸变率"> <div style="height: 265px; position: relative" v-loading="loading">
<template #default="scope"> <vxe-table
<span v-bind="defaultAttribute"
class="conclusion" ref="tableRef1"
:class=" @cell-click="pollutionClick"
scope.row.harmAssessLevel == '特质' height="265px"
? 'background1' :row-config="{ isCurrent: true, isHover: true }"
: scope.row.harmAssessLevel == '较差' :data="pollutionValueList"
? 'background2' style="cursor: pointer"
: scope.row.harmAssessLevel == '极差' >
? 'background3' <vxe-column title="序号" width="60" type="seq"></vxe-column>
: '' <vxe-column field="gdName" title="供电公司" Width="150" />
" <vxe-column field="subStationName" title="变电站" />
> <vxe-column field="projectName" title="项目名称" />
{{ scope.row.harmAssessLevel }} <vxe-column field="subValue" title="谐波电压污染值" width="150" />
</span> </vxe-table>
</template>
</vxe-column> <!-- <MyEChart style="height: 300px" :options="picEChart" @echartClick="echartClick" /> -->
</div>
<vxe-column field="flickerAssessLevel" title="电压闪变"> </el-dialog>
<template #default="scope"> </template>
<span <script setup lang="ts">
class="conclusion" import { ref, nextTick } from 'vue'
:class=" import MyEChart from '@/components/echarts/MyEchart.vue'
scope.row.flickerAssessLevel == '特质' import { defaultAttribute } from '@/components/table/defaultAttribute'
? 'background1' import { useDictData } from '@/stores/dictData'
: scope.row.flickerAssessLevel == '较差' import { getAssessDetail, getAssessTrend, downPollutionSensitiveUser } from '@/api/device-boot/panorama'
? 'background2' import { useRoute } from 'vue-router'
: scope.row.flickerAssessLevel == '极差' const router = useRouter()
? 'background3' const dictData = useDictData()
: '' const dialogVisible: any = ref(false)
" const rowList: any = ref({})
> const type = ref('1')
{{ scope.row.flickerAssessLevel }} const city = ref('0')
</span> const loading = ref(false)
</template> const tableData: any = ref([])
</vxe-column> const subdata: any = ref([])
const picEChart = ref()
<vxe-column field="unbalanceAssessLevel" title="三相电压不平衡度"> const pollutionValueList = ref([])
<template #default="scope"> const tableRef = ref()
<span const loadingTab = ref(false)
class="conclusion" const PollutionList = dictData.getBasicData('Pollution_Calc').filter(item => item.name == '谐波电压')
:class="
scope.row.unbalanceAssessLevel == '特质' const open = async (row: any, list: any) => {
? 'background1'
: scope.row.unbalanceAssessLevel == '较差' // getAssessDetail(row).then(res => {
? 'background2' tableData.value = list
: scope.row.unbalanceAssessLevel == '极差' subdata.value = tableData.value[0]?.powerFlagPollutionList || []
? 'background3' nextTick(() => {
: '' setTimeout(() => {
" tableRef.value?.setCurrentRow(tableData.value[0])
> }, 0)
{{ scope.row.unbalanceAssessLevel }} })
</span> // })
</template> rowList.value = row
</vxe-column> analysis()
</vxe-colgroup> --> dialogVisible.value = true
</vxe-table> }
</div> const currentChangeEvent = async () => {
<div style="height: 300px; margin-top: 10px; position: relative" v-loading="loading"> loadingTab.value = true
<!-- <el-select setTimeout(() => {
v-model="time" subdata.value = tableRef.value.getCurrentRecord()?.powerFlagPollutionList || []
size="small" loadingTab.value = false
}, 1000)
@change="analysis" }
>
<el-option label="年" value="1" /> const analysis = () => {
<el-option label="月" value="3" /> loading.value = true
</el-select> --> let time = rowList.value.searchBeginTime.slice(0, 4) + `-01-01`
<div style="position: absolute; width: 100px; top: 0px; right: 15px; z-index: 1"> downPollutionSensitiveUser({ ...rowList.value, ids: [PollutionList?.[0]?.id], deptId: rowList.value.id }).then(res => {
<el-radio-group v-model="city" size="small" @change="analysis"> pollutionValueList.value = res.data.filter((item: any) => item.subValue != null)
<el-radio-button label="0"></el-radio-button> // const first10Items = res.data.slice(0, 10)
<el-radio-button label="1"></el-radio-button> // picEChart.value = {
</el-radio-group> // title: {
<el-radio-group v-model="type" size="small" @change="analysis"> // text: '污染值排名前十敏感及重要用户'
<el-radio-button label="1"></el-radio-button> // },
<el-radio-button label="3"></el-radio-button>
</el-radio-group> // xAxis: {
</div> // name: '',
// data: first10Items.map((item: any) => item.projectName.split('(')[0].trim()),
<MyEChart style="height: 300px" :options="picEChart" /> // axisLabel: {
</div> // rotate: 20 // 核心:倾斜 45 度(推荐 30/45/60角度太大易读性差
</el-dialog> // }
</template> // },
<script setup lang="ts"> // grid: {
import { ref } from 'vue' // bottom: 10
import MyEChart from '@/components/echarts/MyEchart.vue' // },
import { defaultAttribute } from '@/components/table/defaultAttribute' // legend: {
import { getAssessDetail, getAssessTrend } from '@/api/device-boot/panorama' // show: false
const dialogVisible: any = ref(false) // },
const rowList: any = ref({}) // yAxis: {
const type = ref('1') // name: ''
const city = ref('0') // },
const loading = ref(false) // options: {
const tableData: any = ref([]) // dataZoom: false,
// series: [
const picEChart = ref() // {
const open = async (row: any) => { // // name: time[i],
getAssessDetail(row).then(res => { // name: '污染值',
tableData.value = res.data // type: 'bar',
}) // data: first10Items.map((item: any) => item.subValue),
rowList.value = row // itemStyle: {
analysis() // color: function (params) {
dialogVisible.value = true // // params.value 是当前柱子的数值
} // const value = params.value
const analysis = () => { // return setColor(value)
loading.value = true // }
let time = rowList.value.searchBeginTime.slice(0, 4) + `-01-01` // }
getAssessTrend({ ...rowList.value, searchBeginTime: time, type: type.value, areaType: city.value }).then(res => { // }
picEChart.value = { // ]
title: { // }
text: '各地市综合评估趋势对比' // }
},
legend: { loading.value = false
right: 125, })
top: 20 }
}, const setColor = val => {
// tooltip: { return val == 3.14159
// formatter: function (params: any) { ? ''
// // console.log(123, params) : val > 10000
? '#A52a2a'
// var tips = '' : val > 1000
? '#ff9900'
// for (var i = 0; i < params.length; i++) { : val > 100
// console.log('🚀 ~ getAssessTrend ~ params[i].value:', params[i].value) ? '#ffcc33'
: val > 0
// tips += ? '#3399ff'
// params[i].seriesName + : val == 0
// ':' + ? '#00B07D'
// `<span style="color:${ : ''
// params[i].value > 4.5 }
// ? '' const pollutionClick = (res: any) => {
// : params[i].value > 4 router.push({
// ? '' name: 'harmonic-boot/qydetailedAnalysis/pollutionReport',
// : params[i].value > 3 query: {
// ? '' type: '4',
// : params[i].value > 2 name: res.row.projectName,
// ? '#97017e' t: Date.now()
// : params[i].value > 0 }
// ? '#A52a2a' })
// : '' }
// }"> const clickAttribute = (row: any) => {
// ${ router.push({
// params[i].value > 4.5 name: 'harmonic-boot/qydetailedAnalysis/pollutionReport',
// ? '优质' query: {
// : params[i].value > 4 type: '1',
// ? '良好' name: row.row.lineName,
// : params[i].value > 3 t: Date.now()
// ? '一般' }
// : params[i].value > 2 })
// ? '较差' }
// : params[i].value > 0 defineExpose({ open })
// ? '极差' </script>
// : '' <style lang="scss" scoped>
// } :deep(.el-dialog__body) {
// </span>` + max-height: none !important;
// '</br>' }
// } .conclusion {
// return tips display: inline-block;
// } padding: 0 10px;
// }, height: 24px;
xAxis: { line-height: 24px;
name: '时间',
data: res.data[0].children.map((item: any) => item.dataTime) border-radius: 4px;
}, }
.background1 {
grid: { background-color: #339966;
bottom: '10px', color: #fff;
top: '60px' }
}, .background2 {
background-color: #97017e;
yAxis: { color: #fff;
name: '' }
}, .background3 {
options: { background-color: #a52a2a;
dataZoom: false, color: #fff;
series: [] }
} :deep(.el-select) {
} min-width: 80px !important;
}
let list: any = [] .title {
let time: any = [] display: flex;
let mun: any = [] justify-content: space-between;
res.data.forEach((item: any, num: any) => { position: relative;
time.push(item.deptName)
list.push([]) span {
item.children.forEach((val: any, i: any) => { font-weight: 550;
mun.push(val.score == 3.14159 ? null : val.score) font-size: 18px;
list[num].push(val.score == 3.14159 ? null : val.score) }
})
}) .WarningFilled {
width: 16px;
list.forEach((item: any, i: any) => { cursor: pointer;
picEChart.value.options.series.push({ }
name: time[i], }
type: 'line', </style>
data: item
})
})
picEChart.value.yAxis.min = Math.min(...mun) < 1 ? 0 : (Math.min(...mun) - 0.5).toFixed(2)
picEChart.value.yAxis.max = Math.max(...mun) > 4.5 ? 5 : (Math.max(...mun) + 0.5).toFixed(2)
loading.value = false
})
}
defineExpose({ open })
</script>
<style lang="scss" scoped>
:deep(.el-dialog__body) {
max-height: none !important;
}
.conclusion {
display: inline-block;
padding: 0 10px;
height: 24px;
line-height: 24px;
border-radius: 4px;
}
.background1 {
background-color: #339966;
color: #fff;
}
.background2 {
background-color: #97017e;
color: #fff;
}
.background3 {
background-color: #A52a2a;
color: #fff;
}
:deep(.el-select) {
min-width: 80px !important;
}
</style>

View File

@@ -191,12 +191,12 @@
@click="show = !show" @click="show = !show"
src="@/assets/img/QH.png" src="@/assets/img/QH.png"
/> />
<div class="legeng"> <!-- <div class="legeng">
<div v-for="item in legengList"> <div v-for="item in legengList">
<span :style="`background-color: ${item.color};`"></span> <span :style="`background-color: ${item.color};`"></span>
<span>{{ item.title }}</span> <span>{{ item.title }}</span>
</div> </div>
</div> </div> -->
<!-- 变电站详情 --> <!-- 变电站详情 -->
<stand ref="standRef" /> <stand ref="standRef" />

View File

@@ -149,12 +149,12 @@
@click="show = !show" @click="show = !show"
src="@/assets/img/QH.png" src="@/assets/img/QH.png"
/> />
<div class="legeng"> <!-- <div class="legeng">
<div v-for="item in legengList"> <div v-for="item in legengList">
<span :style="`background-color: ${item.color};`"></span> <span :style="`background-color: ${item.color};`"></span>
<span>{{ item.title }}</span> <span>{{ item.title }}</span>
</div> </div>
</div> </div> -->
<!-- 变电站详情 --> <!-- 变电站详情 -->
<stand ref="standRef" /> <stand ref="standRef" />

View File

@@ -4,26 +4,7 @@
<!-- 综合评估 --> <!-- 综合评估 -->
<div style="height: 110px"> <div style="height: 110px">
<div class="title"> <div class="title">
<span> <span>稳态电能质量水平评估</span>
稳态综合评估
<el-popover placement="right" :width="190" trigger="hover">
<template #reference>
<WarningFilled class="WarningFilled" />
</template>
<div class="text">
<span style="color: #00B07D">优秀:(4.5,5]</span>
<br />
<span style="color: #3399ff">良好:(4,4.5]</span>
<br />
<span style="color: #ffcc33">合格:(3,4]</span>
<br />
<span style="color: #ff9900">较差:(2,3]</span>
<br />
<span style="color: #A52a2a">极差:[1,2]</span>
</div>
</el-popover>
</span>
<span class="info" @click="open(0)"> <span class="info" @click="open(0)">
详情 详情
<ArrowRight style="width: 12px" /> <ArrowRight style="width: 12px" />
@@ -34,58 +15,47 @@
</div> </div>
<div class="mt10 TJTop"> <div class="mt10 TJTop">
<img src="@/assets/img/TJ.png" /> <img src="@/assets/img/TJ.png" />
综合评估得分 区域污染水平评估
<span <el-popover placement="right" :width="190" trigger="hover">
:style="{ <template #reference>
color: <WarningFilled class="WarningFilled ml5" />
assessList.score == 3.14159 </template>
? '' <div class="text">
: assessList.score > 4.5 <span style="color: #00b07d">无污染0</span>
? '#339966' <br />
: assessList.score > 4 <span style="color: #3399ff">轻微污染(0 , 100]</span>
? '#2b7fd3' <br />
: assessList.score > 3 <span style="color: #ffcc33">轻度污染(100 , 1000]</span>
? '#ffcc33' <br />
: assessList.score > 2 <span style="color: #ff9900">中度污染(1000 , 10000]</span>
? '#97017e' <br />
: assessList.score > 0 <span style="color: #a52a2a">重度污染(10000</span>
? '#A52a2a' </div>
: '' </el-popover>
}"
>
{{ assessList.score == 3.14159 ? '/' : assessList.score }}
</span>
</div> </div>
<div class="evaluate"> <div class="evaluate">
<div v-for="item in assessList.children" style="min-width: 50px"> <div v-for="item in assessList" style="min-width: 60px" class="mb3">
<div> <div>
<span class="line"></span> <span
{{ item.name }} class="line"
:style="{
background: setColor(item.score)
}"
></span>
{{ item.deptName }}
</div> </div>
<div <div
style="margin-top: 5px" style="margin-top: 5px"
:style="{ :style="{
color: color: setColor(item.score)
item.score == 3.14159
? ''
: item.score > 4.5
? '#339966'
: item.score > 4
? '#2b7fd3'
: item.score > 3
? '#ffcc33'
: item.score > 2
? '#97017e'
: item.score > 0
? '#A52a2a'
: ''
}" }"
> >
{{ item.score == 3.14159 ? '/' : item.score }} {{ setVal(item.score) }}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- 稳态电能质量水平评估 --> <!-- 稳态电能质量水平评估 -->
<div> <div>
<div class="title"> <div class="title">
@@ -108,7 +78,13 @@
</span> </span>
</div> </div>
<el-select v-model="harmonicType" style="width: 120px" @change="harmonicChange" size="small" filterable> <el-select
v-model="harmonicType"
style="width: 120px"
@change="harmonicChange"
size="small"
filterable
>
<el-option <el-option
v-for="item in options" v-for="item in options"
:key="item.value" :key="item.value"
@@ -155,7 +131,13 @@
</div> </div>
</div> </div>
<el-select v-model="value" style="width: 120px" size="small" @change="transientChange" filterable> <el-select
v-model="value"
style="width: 120px"
size="small"
@change="transientChange"
filterable
>
<el-option v-for="item in options1" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in options1" :key="item.id" :label="item.name" :value="item.id" />
</el-select> </el-select>
</div> </div>
@@ -259,6 +241,7 @@ import temporaryState from './details/temporaryState.vue'
import technique from './details/technique.vue' import technique from './details/technique.vue'
import { import {
getAssessOverview, getAssessOverview,
getAreaPollution,
getEvaluationOverview, getEvaluationOverview,
getEventLevelEvaluation, getEventLevelEvaluation,
getSupervisionData getSupervisionData
@@ -314,8 +297,7 @@ const options = ref([
{ {
label: '负序电流', label: '负序电流',
value: '9' value: '9'
}, }
]) ])
const technology: any = ref({}) const technology: any = ref({})
const harmonicType = ref('6') const harmonicType = ref('6')
@@ -364,17 +346,16 @@ const JDlist = ref([
{ {
name: '试运行问题', name: '试运行问题',
value: 0 value: 0
}, }
]) ])
const harmonicList: any = ref([]) const harmonicList: any = ref([])
const harmonicLineRatio: any = ref(0) const harmonicLineRatio: any = ref(0)
const WTList: any = ref([]) const WTList: any = ref([])
const PollutionList = dictData.getBasicData('Pollution_Calc')?.filter(item => item.name == '谐波电压')
const value = ref(options1[0].id) const value = ref(options1[0].id)
const open = (e: number) => { const open = (e: number) => {
if (e == 0) { if (e == 0) {
evaluateRef.value.open(formRow.value) evaluateRef.value.open(formRow.value, assessList.value)
} else if (e == 1) { } else if (e == 1) {
steadyStateRef.value.open(formRow.value) steadyStateRef.value.open(formRow.value)
} else if (e == 2) { } else if (e == 2) {
@@ -383,6 +364,36 @@ const open = (e: number) => {
techniqueRef.value.open(formRow.value) techniqueRef.value.open(formRow.value)
} }
} }
const setColor = (val: any) => {
return val == 3.14159
? ''
: val > 10000
? '#A52a2a'
: val > 1000
? '#ff9900'
: val > 100
? '#ffcc33'
: val > 0
? '#3399ff'
: val == 0
? '#00B07D'
: ''
}
const setVal = (val: any) => {
return val == 3.14159
? '/'
: val > 10000
? '重度'
: val > 1000
? '中度'
: val > 100
? '轻度'
: val > 0
? '轻微'
: val == 0
? '无'
: ''
}
const info = (row: any) => { const info = (row: any) => {
let form = { let form = {
...row, ...row,
@@ -402,7 +413,10 @@ const info = (row: any) => {
transientChange() transientChange()
// 综合评估 // 综合评估
setTimeout(() => { setTimeout(() => {
getAssessOverview(form).then(res => { // getAssessOverview(form).then(res => {
// assessList.value = res.data
// })
getAreaPollution({ ...form, ids: [PollutionList?.[0]?.id] }).then(res => {
assessList.value = res.data assessList.value = res.data
}) })
}, 300) }, 300)
@@ -413,8 +427,7 @@ const info = (row: any) => {
JDlist.value[1].value = res.data?.onLineNum || 0 JDlist.value[1].value = res.data?.onLineNum || 0
JDlist.value[2].value = res.data?.userNum || 0 JDlist.value[2].value = res.data?.userNum || 0
JDlist.value[3].value = res.data?.trialRunNum || 0 JDlist.value[3].value = res.data?.trialRunNum || 0
})
})
} }
const harmonicChange = () => { const harmonicChange = () => {
getEvaluationOverview({ ...formRow.value, harmonicType: harmonicType.value }).then(res => { getEvaluationOverview({ ...formRow.value, harmonicType: harmonicType.value }).then(res => {
@@ -476,11 +489,11 @@ defineExpose({ info, show })
cursor: pointer; cursor: pointer;
color: #757575; color: #757575;
} }
.WarningFilled { }
width: 12px; .WarningFilled {
font-weight: 500; width: 12px;
cursor: pointer; font-weight: 500;
} cursor: pointer;
} }
.TJTop { .TJTop {
display: flex; display: flex;

View File

@@ -29,7 +29,7 @@
</vxe-column> </vxe-column>
</vxe-table> </vxe-table>
</div> </div>
<div class="ml10" style="width: 990px"> <div class="ml10 pr20" style="width: 980px">
<vxe-table <vxe-table
v-bind="defaultAttribute" v-bind="defaultAttribute"
@cell-click="clickAttribute" @cell-click="clickAttribute"