联调 有功功率趋势分析

This commit is contained in:
GGJ
2024-08-29 15:58:30 +08:00
parent 1fa628044f
commit 3ac62fc98c
4 changed files with 251 additions and 149 deletions

View File

@@ -24,3 +24,21 @@ export function getTargetByTime(data: any) {
data: data data: data
}) })
} }
// 导出报告参数
export function exportExcelListTemplate(data: any) {
return request({
url: '/harmonic-boot/powerStatistics/exportExcelListTemplate',
method: 'POST',
data: data,
responseType: 'blob'
})
}
// 导出区间数据
export function exportExcelRangTemplate(data: any) {
return request({
url: '/harmonic-boot/powerStatistics/exportExcelRangTemplate',
method: 'POST',
data: data,
responseType: 'blob'
})
}

View File

@@ -107,7 +107,9 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
response.data.type === 'application/json' || response.data.type === 'application/json' ||
Array.isArray(response.data) || Array.isArray(response.data) ||
response.data.size || response.data.size ||
response.config.url == '/harmonic-boot/exportmodel/exportModelJB' response.config.url == '/harmonic-boot/exportmodel/exportModelJB' ||
response.config.url == '/harmonic-boot/powerStatistics/exportExcelListTemplate' ||
response.config.url == '/harmonic-boot/powerStatistics/exportExcelRangTemplate'
// || // ||
// response.data.type === 'application/octet-stream' || // response.data.type === 'application/octet-stream' ||
// response.data.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' // response.data.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

View File

@@ -45,8 +45,9 @@ const popupEditRef = ref()
const tableStore = new TableStore({ const tableStore = new TableStore({
url: '/harmonic-boot/powerStatistics/getTargetByTime', url: '/harmonic-boot/powerStatistics/getTargetByTime',
method: 'POST', method: 'POST',
showPage: false,
column: [ column: [
{ title: '指标', field: 'name' }, { title: '指标', field: 'anotherName' },
{ {
title: '最小值', title: '最小值',
field: 'code', field: 'code',
@@ -86,23 +87,12 @@ const tableStore = new TableStore({
], ],
beforeSearchFun: () => { beforeSearchFun: () => {
tableStore.table.params.field = props.timePopUpBox.field tableStore.table.params.field = props.timePopUpBox.field
tableStore.table.params.lineId = props.timePopUpBox.lineId tableStore.table.params.lineId = '6469e77fda42db12c7ca6620a092f03c' //props.timePopUpBox.lineId
tableStore.table.params.searchBeginTime = props.timePopUpBox.time tableStore.table.params.searchBeginTime = props.timePopUpBox.time
tableStore.table.params.searchEndTime = props.timePopUpBox.time tableStore.table.params.searchEndTime = props.timePopUpBox.time
tableStore.table.params.statisticalId = radio2.value tableStore.table.params.statisticalId = radio2.value
}, },
loadCallback: () => { loadCallback: () => {}
tableStore.table.data = [
{ name: '电压偏差(%)', num: 0.0 },
{ name: '谐波电压(%)', num: 0.0 },
{ name: '谐波电流(%)', num: 0.0 },
{ name: '三相电压不平衡度(%)', num: 0.0 },
{ name: '电压波动(%)', num: 0.0 },
{ name: '闪变(%)', num: 0.0 },
{ name: '间谐波电压含有率(%)', num: 0.0 },
{ name: '电流不平衡度', num: 0.0 }
]
}
}) })
provide('tableStore', tableStore) provide('tableStore', tableStore)

View File

@@ -10,44 +10,8 @@
</pane> </pane>
<pane :style="height" style="background: #fff"> <pane :style="height" style="background: #fff">
<TableHeader ref="TableHeaderRef" datePicker> <TableHeader ref="TableHeaderRef" datePicker>
<template v-slot:select>
<!-- <el-form-item label="有功功率区间">
<el-select
v-model="power"
multiple
collapse-tags
collapse-tags-tooltip
filterable
placeholder="请选择有功功率区间"
>
<el-option
v-for="item in powerList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="各指标越限">
<el-select
v-model="index"
multiple
collapse-tags
collapse-tags-tooltip
filterable
placeholder="请选择各指标越限"
>
<el-option
v-for="item in indexList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item> -->
</template>
<template #operation> <template #operation>
<el-button icon="el-icon-Download" type="primary">生成报表</el-button> <el-button icon="el-icon-Download" type="primary" @click="exportData">导出区间数据</el-button>
</template> </template>
</TableHeader> </TableHeader>
@@ -104,15 +68,22 @@
</el-card> </el-card>
</div> </div>
<el-card class="echart"> <el-card class="echart">
<my-echart :options="options" style="height: 238px" /> <h3>有功率区间占比</h3>
<my-echart :options="options" style="height: 208px" />
</el-card> </el-card>
</div> </div>
<div class="container mt10 ml10"> <div class="container mt10 ml10">
<el-card class="box"> <el-card class="box">
<h3>功率区间稳态越限详情</h3> <h3>功率区间稳态越限详情</h3>
<div :style="`height:calc(${heightB.height} - 25px)`" style="overflow-y: auto"> <div :style="`height:calc(${heightB.height} - 25px)`" style="overflow-y: auto">
<vxe-table v-bind="defaultAttribute" ref="vxeRef" height="auto" :data="tableData"> <vxe-table
<vxe-column field="num" title="时间" min-width="100px"> v-bind="defaultAttribute"
ref="vxeRef"
height="auto"
:data="tableData"
v-loading="loading"
>
<vxe-column field="num" title="时间" width="180px">
<template #default="{ row }"> <template #default="{ row }">
<el-link <el-link
type="primary" type="primary"
@@ -129,7 +100,7 @@
<el-link <el-link
:type="row.voltageOffset == '1' ? 'danger' : 'success'" :type="row.voltageOffset == '1' ? 'danger' : 'success'"
class="percentage" class="percentage"
@click="timeClick(row)" @click="detailClick(row)"
> >
{{ row.voltageOffset == '1' ? '越限' : '合格' }} {{ row.voltageOffset == '1' ? '越限' : '合格' }}
</el-link> </el-link>
@@ -140,7 +111,7 @@
<el-link <el-link
:type="row.vtimes == '1' ? 'danger' : 'success'" :type="row.vtimes == '1' ? 'danger' : 'success'"
class="percentage" class="percentage"
@click="timeClick(row)" @click="detailClick(row)"
> >
{{ row.vtimes == '1' ? '越限' : '合格' }} {{ row.vtimes == '1' ? '越限' : '合格' }}
</el-link> </el-link>
@@ -151,7 +122,7 @@
<el-link <el-link
:type="row.itimes == '1' ? 'danger' : 'success'" :type="row.itimes == '1' ? 'danger' : 'success'"
class="percentage" class="percentage"
@click="timeClick(row)" @click="detailClick(row)"
> >
{{ row.itimes == '1' ? '越限' : '合格' }} {{ row.itimes == '1' ? '越限' : '合格' }}
</el-link> </el-link>
@@ -162,7 +133,7 @@
<el-link <el-link
:type="row.ubalance == '1' ? 'danger' : 'success'" :type="row.ubalance == '1' ? 'danger' : 'success'"
class="percentage" class="percentage"
@click="timeClick(row)" @click="detailClick(row)"
> >
{{ row.ubalance == '1' ? '越限' : '合格' }} {{ row.ubalance == '1' ? '越限' : '合格' }}
</el-link> </el-link>
@@ -173,7 +144,7 @@
<el-link <el-link
:type="row.voltageFluctuation == '1' ? 'danger' : 'success'" :type="row.voltageFluctuation == '1' ? 'danger' : 'success'"
class="percentage" class="percentage"
@click="timeClick(row)" @click="detailClick(row)"
> >
{{ row.voltageFluctuation == '1' ? '越限' : '合格' }} {{ row.voltageFluctuation == '1' ? '越限' : '合格' }}
</el-link> </el-link>
@@ -184,7 +155,7 @@
<el-link <el-link
:type="row.flicker == '1' ? 'danger' : 'success'" :type="row.flicker == '1' ? 'danger' : 'success'"
class="percentage" class="percentage"
@click="timeClick(row)" @click="detailClick(row)"
> >
{{ row.flicker == '1' ? '越限' : '合格' }} {{ row.flicker == '1' ? '越限' : '合格' }}
</el-link> </el-link>
@@ -195,7 +166,7 @@
<el-link <el-link
:type="row.interHarmonic == '1' ? 'danger' : 'success'" :type="row.interHarmonic == '1' ? 'danger' : 'success'"
class="percentage" class="percentage"
@click="timeClick(row)" @click="detailClick(row)"
> >
{{ row.interHarmonic == '1' ? '越限' : '合格' }} {{ row.interHarmonic == '1' ? '越限' : '合格' }}
</el-link> </el-link>
@@ -206,14 +177,14 @@
<el-link <el-link
:type="row.sequenceCurrentUnbalance == '1' ? 'danger' : 'success'" :type="row.sequenceCurrentUnbalance == '1' ? 'danger' : 'success'"
class="percentage" class="percentage"
@click="timeClick(row)" @click="detailClick(row)"
> >
{{ row.sequenceCurrentUnbalance == '1' ? '越限' : '合格' }} {{ row.sequenceCurrentUnbalance == '1' ? '越限' : '合格' }}
</el-link> </el-link>
</template> </template>
</vxe-column> </vxe-column>
<vxe-column field="num3" title="操作"> <vxe-column field="num3" title="操作" width="80">
<template #default="{ row }"> <template #default="{ row }">
<el-button type="primary" link @click="addTo(row)">添加</el-button> <el-button type="primary" link @click="addTo(row)">添加</el-button>
</template> </template>
@@ -226,13 +197,17 @@
<div :style="heightB" style="overflow-y: auto"> <div :style="heightB" style="overflow-y: auto">
<div style="display: flex; justify-content: space-between"> <div style="display: flex; justify-content: space-between">
<span style="font-size: 16px; font-weight: 700">报告参数</span> <span style="font-size: 16px; font-weight: 700">报告参数</span>
<el-button icon="el-icon-Download" size="small" type="primary">生成报表</el-button> <el-button icon="el-icon-Download" size="small" type="primary" @click="generateReports">
生成报表
</el-button>
</div> </div>
<div> <div>
<el-tree style="max-width: 600px" :data="dataSource" node-key="id" default-expand-all> <el-tree style="max-width: 600px" :data="dataSource" node-key="id" default-expand-all>
<template #default="{ node, data }"> <template #default="{ node, data }">
<span class="custom-tree-node"> <span class="custom-tree-node">
<span style="color: var(--el-color-primary)">{{ data.time }}</span> <span :style="data.level != 0 ? 'color: var(--el-color-primary)' : ''">
{{ data.time }}
</span>
<Close <Close
v-if="data.level != 0" v-if="data.level != 0"
style="margin-left: 5px; height: 14px" style="margin-left: 5px; height: 14px"
@@ -271,7 +246,13 @@ import { mainHeight } from '@/utils/layout'
import { defaultAttribute } from '@/components/table/defaultAttribute' import { defaultAttribute } from '@/components/table/defaultAttribute'
import MyEchart from '@/components/echarts/MyEchart.vue' import MyEchart from '@/components/echarts/MyEchart.vue'
import TimePopUpBox from './components/timePopUpBox.vue' import TimePopUpBox from './components/timePopUpBox.vue'
import { getDataByLineId, getTargetLimitById, getTargetByTime } from '@/api/harmonic-boot/newEnergyAnalysis' import { ElMessage } from 'element-plus'
import {
getDataByLineId,
getTargetLimitById,
exportExcelRangTemplate,
exportExcelListTemplate
} from '@/api/harmonic-boot/newEnergyAnalysis'
import detail from './components/detail.vue' import detail from './components/detail.vue'
import { Close } from '@element-plus/icons-vue' import { Close } from '@element-plus/icons-vue'
defineOptions({ defineOptions({
@@ -279,17 +260,17 @@ defineOptions({
}) })
const timePopUpBox = ref<anyObj | null>(null) const timePopUpBox = ref<anyObj | null>(null)
const flag = ref('0%~10%') const flag = ref('0%~10%')
const radio2 = ref('1')
const height = mainHeight(20) const height = mainHeight(20)
const heightB = mainHeight(395) const heightB = mainHeight(395)
const size = ref(0) const size = ref(0)
const TableHeaderRef = ref() const TableHeaderRef = ref()
const detailRef = ref() const detailRef = ref()
const dotList: any = ref({}) const dotList: any = ref({})
const loading = ref(false)
const timePopUpBoxRef = ref() const timePopUpBoxRef = ref()
const index = ref(0) const index = ref(0)
const treeList = ref([])
const powerList1: any = ref([ const powerList1: any = ref([
{ {
label: '0%~10%', label: '0%~10%',
@@ -455,126 +436,106 @@ const remove = (node: any, data: any) => {
children.splice(index, 1) children.splice(index, 1)
dataSource.value = [...dataSource.value] dataSource.value = [...dataSource.value]
} }
const options = ref({}) const options = ref({})
const tableStore = new TableStore({ const tableStore = new TableStore({
url: '', url: '/harmonic-boot/powerStatistics/getDataByLineId',
method: 'POST', method: 'POST',
column: [], column: [],
beforeSearchFun: () => {}, beforeSearchFun: () => {
loadCallback: () => {} treeList.value = dotList.value
})
// 卡片点击变色 tableStore.table.params.lineId = dotList.value.id
tableStore.table.params.searchBeginTime = TableHeaderRef.value.datePickerRef.timeValue[0]
tableStore.table.params.searchEndTime = TableHeaderRef.value.datePickerRef.timeValue[1]
},
loadCallback: () => {
let res = tableStore.table.data
// 点击时间
const timeClick = (row: any) => {
let data = {
...row,
field: index.value,
lineId: dotList.value.id
}
timePopUpBox.value = data
}
// 点击越限
const detailClick = (row: any) => {
detailRef.value.open()
}
// 获取有功功率趋势分析数据
const analyse = (e: any) => {
getDataByLineId({
lineId: e.id,
searchBeginTime: TableHeaderRef.value.datePickerRef.timeValue[0],
searchEndTime: TableHeaderRef.value.datePickerRef.timeValue[1]
}).then(res => {
let mun = let mun =
res.data.minsNum1 + res.minsNum1 +
res.data.minsNum2 + res.minsNum2 +
res.data.minsNum3 + res.minsNum3 +
res.data.minsNum4 + res.minsNum4 +
res.data.minsNum5 + res.minsNum5 +
res.data.minsNum6 + res.minsNum6 +
res.data.minsNum7 + res.minsNum7 +
res.data.minsNum8 + res.minsNum8 +
res.data.minsNum9 res.minsNum9
powerList1.value = [ powerList1.value = [
{ {
label: '0%~10%', label: '0%~10%',
quantity: res.data.minsNum0, quantity: res.minsNum0,
percentage: ((res.data.minsNum0 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum0 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot0, crossTheLine: res.isOrNot0,
value: '0%~10%' value: '0%~10%'
}, },
{ {
label: '10%~20%', label: '10%~20%',
quantity: res.data.minsNum1, quantity: res.minsNum1,
percentage: ((res.data.minsNum1 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum1 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot1, crossTheLine: res.isOrNot1,
value: '10%~10%' value: '10%~10%'
}, },
{ {
label: '20%~30%', label: '20%~30%',
quantity: res.data.minsNum2, quantity: res.minsNum2,
percentage: ((res.data.minsNum2 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum2 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot2, crossTheLine: res.isOrNot2,
value: '10%~30%' value: '10%~30%'
}, },
{ {
label: '30%~40%', label: '30%~40%',
quantity: res.data.minsNum3, quantity: res.minsNum3,
percentage: ((res.data.minsNum3 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum3 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot3, crossTheLine: res.isOrNot3,
value: '30%~40%' value: '30%~40%'
}, },
{ {
label: '40%~50%', label: '40%~50%',
quantity: res.data.minsNum4, quantity: res.minsNum4,
percentage: ((res.data.minsNum4 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum4 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot4, crossTheLine: res.isOrNot4,
value: '40%~50%' value: '40%~50%'
} }
] ]
powerList2.value = [ powerList2.value = [
{ {
label: '50%~60%', label: '50%~60%',
quantity: res.data.minsNum5, quantity: res.minsNum5,
percentage: ((res.data.minsNum5 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum5 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot5, crossTheLine: res.isOrNot5,
value: '50%~60%' value: '50%~60%'
}, },
{ {
label: '60%~70%', label: '60%~70%',
quantity: res.data.minsNum6, quantity: res.minsNum6,
percentage: ((res.data.minsNum6 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum6 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot6, crossTheLine: res.isOrNot6,
value: '60%~70%' value: '60%~70%'
}, },
{ {
label: '70%~80%', label: '70%~80%',
quantity: res.data.minsNum7, quantity: res.minsNum7,
percentage: ((res.data.minsNum7 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum7 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot7, crossTheLine: res.isOrNot7,
value: '70%~80%' value: '70%~80%'
}, },
{ {
label: '80%~90%', label: '80%~90%',
quantity: res.data.minsNum8, quantity: res.minsNum8,
percentage: ((res.data.minsNum8 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum8 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot8, crossTheLine: res.isOrNot8,
value: '80%~90%' value: '80%~90%'
}, },
{ {
label: '90%~100%', label: '90%~100%',
quantity: res.data.minsNum9, quantity: res.minsNum9,
percentage: ((res.data.minsNum9 / mun) * 100).toFixed(2) + '%', percentage: ((res.minsNum9 / mun || 0) * 100).toFixed(2) + '%',
crossTheLine: res.data.isOrNot9, crossTheLine: res.isOrNot9,
value: '90%~100%' value: '90%~100%'
} }
] ]
options.value = { options.value = {
title: {
text: '有功率区间占比',
left: '10px'
},
legend: { legend: {
show: false show: false
}, },
@@ -625,20 +586,155 @@ const analyse = (e: any) => {
] ]
} }
} }
dataSource.value = [
{
id: 1,
level: 0,
time: '0%~10%',
children: []
},
{
id: 2,
level: 0,
time: '10%~20%',
children: []
},
{
id: 3,
level: 0,
time: '20%~30%',
children: []
},
{
id: 4,
level: 0,
time: '30%~40%',
children: []
},
{
id: 5,
level: 0,
time: '40%~50%',
children: []
},
{
id: 6,
level: 0,
time: '50%~60%',
children: []
},
{
id: 7,
level: 0,
time: '60%~70%',
children: []
},
{
id: 8,
level: 0,
time: '70%~80%',
children: []
},
{
id: 9,
level: 0,
time: '80%~90%',
children: []
},
{
id: 10,
level: 0,
time: '90%~100%',
children: []
}
]
analyseList(flag.value, index.value)
}
})
// 导出区间数据
const exportData = () => {
ElMessage('正在下载中,请稍等...')
exportExcelRangTemplate({
lineId: dotList.value.id,
searchBeginTime: tableStore.table.params.searchBeginTime,
searchEndTime: tableStore.table.params.searchEndTime
}).then((res: any) => {
let blob = new Blob([res], {
type: 'application/vnd.ms-excel'
})
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a') // 创建a标签
link.href = url
link.download = treeList.value?.name + ' 0%-100% 区间数据' // 设置下载的文件名
document.body.appendChild(link)
link.click() //执行下载
document.body.removeChild(link)
}) })
} }
// 导出报告参数
const generateReports = () => {
let data: any = {
lineId: dotList.value.id,
searchBeginTime: tableStore.table.params.searchBeginTime,
searchEndTime: tableStore.table.params.searchEndTime
}
dataSource.value.forEach((item: any, i: number) => {
// item.children
data[`time${i}`] = item.children.map((it: any) => it.time)
}),
exportExcelListTemplate(data).then((res: any) => {
let blob = new Blob([res], {
type: 'application/vnd.ms-excel'
})
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a') // 创建a标签
link.href = url
link.download = treeList.value?.name +' 报告' // 设置下载的文件名
document.body.appendChild(link)
link.click() //执行下载
document.body.removeChild(link)
})
}
// 点击时间
const timeClick = (row: any) => {
let data = { ...row, field: index.value, lineId: dotList.value.id }
timePopUpBox.value = data
}
// 点击越限
const detailClick = (row: any) => {
detailRef.value.open()
}
// // 获取有功功率趋势分析数据
// const analyse = (e: any) => {
// getDataByLineId({
// lineId: e.id,
// searchBeginTime: tableStore.table.params.searchBeginTime,
// searchEndTime: tableStore.table.params.searchEndTime
// }).then(res => {})
// }
// 功率列表 // 功率列表
const analyseList = (e: string, i: number) => { const analyseList = (e: string, i: number) => {
flag.value = e flag.value = e
index.value = i index.value = i
loading.value = true
getTargetLimitById({ getTargetLimitById({
lineId: dotList.value.id, lineId: dotList.value.id,
searchBeginTime: TableHeaderRef.value.datePickerRef.timeValue[0], searchBeginTime: tableStore.table.params.searchBeginTime,
searchEndTime: TableHeaderRef.value.datePickerRef.timeValue[1], searchEndTime: tableStore.table.params.searchEndTime,
statisticalId: i statisticalId: i
}).then(res => {
tableData.value = res.data
}) })
.then(res => {
loading.value = false
tableData.value = res.data
})
.catch(() => {
loading.value = false
})
} }
provide('tableStore', tableStore) provide('tableStore', tableStore)
@@ -649,16 +745,12 @@ onMounted(() => {
size.value = Math.round((180 / dom.offsetHeight) * 100) size.value = Math.round((180 / dom.offsetHeight) * 100)
} }
}) })
let control = ref(true)
const handleNodeClick = (data: any, node: any) => { const handleNodeClick = (data: any, node: any) => {
console.log('🚀 ~ handleNodeClick ~ data:', data) console.log('🚀 ~ handleNodeClick ~ data:', data)
if (data.level == 6) { if (data.level == 6) {
dotList.value = data dotList.value = data
analyse(data) tableStore.index()
if (control.value) {
analyseList('0%~10%', 0)
control.value = false
}
} }
} }
</script> </script>