Files
admin-sjzx/src/views/pqs/harmonicMonitoring/detailed/pollutionReport/index.vue
2025-09-11 13:43:39 +08:00

463 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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 full-height">
<TableHeader datePicker ref="TableHeaderRef">
<template #select>
<el-form-item label="区域">
<el-cascader
v-bind="$attrs"
:options="areOptions"
:props="cascaderProps"
v-model="selectedArea"
@change="handleFilterChange"
/>
</el-form-item>
<el-form-item label="统计类型">
<el-select
v-model="tableStore.table.params.statisticalType"
value-key="id"
placeholder="请选择统计类型"
@change="handleStatisticalTypeChange"
>
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item" />
</el-select>
</el-form-item>
<el-form-item label="电网标志">
<el-select
v-model="tableStore.table.params.powerFlag"
placeholder="请选择电网标志"
@change="handleFilterChange"
>
<el-option label="全部" value="0"></el-option>
<el-option label="电网侧" value="1"></el-option>
<el-option label="非电网侧" value="2"></el-option>
</el-select>
</el-form-item>
<!-- 添加其他前端过滤条件 -->
<el-form-item label="变电站">
<el-input
v-model="localFilters.subStationName"
placeholder="请输入变电站名称"
clearable
@input="handleFilterChange"
/>
</el-form-item>
<el-form-item label="终端名称">
<el-input
v-model="localFilters.devName"
placeholder="请输入终端名称"
clearable
@input="handleFilterChange"
/>
</el-form-item>
<el-form-item label="监测点名称">
<el-input
v-model="localFilters.lineName"
placeholder="请输入监测点名称"
clearable
@input="handleFilterChange"
/>
</el-form-item>
</template>
<template #operation>
<el-button icon="el-icon-Download" type="primary" @click="exportEvent">导出</el-button>
</template>
</TableHeader>
<div v-loading="tableStore.table.loading" class="table-container">
<vxe-table
class="full-height-table"
ref="positioningtableRef"
auto-resize
:data="tableStore.table.data"
v-bind="defaultAttribute"
:height="tableHeight"
resizable
show-overflow
>
<vxe-column title="序号" width="80" type="seq" align="center"></vxe-column>
<vxe-column field="gdName" title="供电公司" align="center" min-width="120"></vxe-column>
<vxe-column field="subStationName" :show-overflow="true" title="变电站" align="center" min-width="150" width="230"></vxe-column>
<vxe-column field="devName" title="终端名称" align="center" min-width="120"></vxe-column>
<vxe-column field="devType" title="终端型号" align="center" min-width="150" width="200"></vxe-column>
<vxe-column field="loginTime" title="投运时间" align="center" min-width="120"></vxe-column>
<vxe-column field="lineName" title="监测点名称" align="center" min-width="150"></vxe-column>
<vxe-column field="powerFlag" title="监测位置" align="center" min-width="100"></vxe-column>
<vxe-column field="lineVoltage" title="监测点电压等级" align="center" min-width="120"></vxe-column>
<vxe-column field="loadType" title="干扰源类型" align="center" min-width="120"></vxe-column>
<vxe-column field="objName" title="监测对象名称" align="center" min-width="150" width="200"></vxe-column>
<vxe-column field="onlineRate" title="在线率" align="center" min-width="100"></vxe-column>
<vxe-column field="integrity" title="完整率" align="center" min-width="100"></vxe-column>
<vxe-column field="harmonicValue" :title="harmonicValueTitle" align="center" min-width="120"></vxe-column>
<vxe-column field="upCounts" title="暂升次数(次)" align="center" min-width="100"></vxe-column>
<vxe-column field="downCounts" title="电压暂降(次)" align="center" min-width="100"></vxe-column>
<vxe-column field="breakCounts" title="短时中断(次)" align="center" min-width="100"></vxe-column>
<vxe-column field="monitorId" title="一类监测点" align="center" min-width="120" :formatter="formatMonitorId"></vxe-column>
</vxe-table>
<!-- 修改分页控件 -->
<div class="pagination-container">
<el-pagination
:current-page="tableStore.table.params.pageNum"
:page-size="tableStore.table.params.pageSize"
:page-sizes="[10, 20, 50, 100]"
background
layout="sizes, total, prev, pager, next, jumper"
:total="tableStore.table.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, provide, onBeforeUnmount, computed, reactive, watch } from 'vue'
import TableStore from '@/utils/tableStore'
import TableHeader from '@/components/table/header/index.vue'
import { defaultAttribute } from '@/components/table/defaultAttribute'
import { useDictData } from '@/stores/dictData'
import { debounce } from 'lodash-es'
defineOptions({
name: 'harmonic-boot/qydetailedAnalysis/pollutionReport'
})
const dictData = useDictData()
const options = dictData.getBasicData('Pollution_Calc')
const tableHeight = ref(500) // 默认高度
const positioningtableRef = ref()
// 添加区域选择的响应式变量
const selectedArea = ref()
const areOptions:any = dictData.state.area
const allData = ref<PollutionItem[]>([])
const TableHeaderRef = ref()
// 添加响应式标题变量
const harmonicValueTitle = ref('谐波电压污染值')
const cascaderProps = {
label: 'name',
value: 'id',
checkStrictly: true,
emitPath: false
}
// 存储所有数据
interface PollutionItem {
gdName?: string
subStationName?: string
devName?: string
lineName?: string
powerFlag?: string
}
// 格式化一类监测点字段
const formatMonitorId = (row: any) => {
return row.row.monitorId || '/'
}
// 本地过滤参数
const localFilters = reactive({
gdName: '',
subStationName: '',
devName: '',
lineName: '',
powerFlag: '0' // 本地存储电网标志值
})
// 计算表格高度
const calculateTableHeight = () => {
const windowHeight = window.innerHeight
const headerHeight = 120
const paginationHeight = 50
const padding = 20
tableHeight.value = windowHeight - headerHeight - paginationHeight - padding
}
// 防抖处理窗口大小变化
const debouncedCalculateTableHeight = debounce(() => {
calculateTableHeight()
}, 300)
// 计算过滤后的数据
const filteredData = computed(() => {
let result = [...allData.value]
// 区域过滤
if (selectedArea.value) {
// 查找匹配的区域名称
let areaName = ''
let areaLevel = -1
const findAreaName = (areas: any[]) => {
for (const area of areas) {
if (area.id === selectedArea.value) {
areaName = area.name
areaLevel = area.level !== undefined ? area.level : -1
break
}
if (area.children && area.children.length > 0) {
findAreaName(area.children)
}
}
}
findAreaName(areOptions)
// 根据区域名称过滤数据但只有当层级大于1时才过滤
if (areaName && areaLevel > 1) {
result = result.filter(item => item.gdName && item.gdName.includes(areaName))
}
}
// 电网标志过滤
if (localFilters.powerFlag === '1') {
// 电网侧
result = result.filter(item => item.powerFlag && !item.powerFlag.includes('非'))
} else if (localFilters.powerFlag === '2') {
// 非电网侧
result = result.filter(item => item.powerFlag && item.powerFlag.includes('非'))
}
// '0' 表示全部,不过滤
// 变电站过滤
if (localFilters.subStationName) {
result = result.filter(item => item.subStationName && item.subStationName.includes(localFilters.subStationName))
}
// 终端名称过滤
if (localFilters.devName) {
result = result.filter(item => item.devName && item.devName.includes(localFilters.devName))
}
// 监测点名称过滤
if (localFilters.lineName) {
result = result.filter(item => item.lineName && item.lineName.includes(localFilters.lineName))
}
return result
})
// 计算当前页数据
const currentPageData = computed(() => {
const pageSize = tableStore.table.params.pageSize
const pageNum = tableStore.table.params.pageNum
const start = (pageNum - 1) * pageSize
const end = start + pageSize
return filteredData.value.slice(start, end)
})
// 更新总条数
const updateTotal = computed(() => {
return filteredData.value.length
})
const tableStore = new TableStore({
url: '/harmonic-boot/PollutionSubstation/downPollutionLineCalc',
method: 'POST',
column: [],
beforeSearchFun: () => {
//delete tableStore.table.params.statisticalType
delete tableStore.table.params.deptIndex
delete tableStore.table.params.interval
delete tableStore.table.params.searchEndTime
delete tableStore.table.params.searchBeginTime
delete tableStore.table.params.timeFlag
},
loadCallback: () => {
// 将所有数据存储到 allData 中
allData.value = tableStore.table.data || []
// 更新总条数
tableStore.table.total = updateTotal.value
// 更新当前页数据
tableStore.table.data = currentPageData.value
}
})
provide('tableStore', tableStore)
// 监听区域选项变化,设置默认值
watch(
() => areOptions,
(newOptions) => {
if (newOptions && newOptions.length > 0) {
// 设置默认选中第一项
selectedArea.value = newOptions[0].id
tableStore.table.params.id = newOptions[0].id
}
},
{ immediate: true }
)
// 初始化统计类型
watch(
() => options,
(newOptions) => {
if (newOptions && newOptions.length > 0) {
// 检查是否已经设置了统计类型
if (!tableStore.table.params.statisticalType) {
tableStore.table.params.statisticalType = newOptions[0]
tableStore.table.params.ids = [newOptions[0].id]
}
}
},
{ immediate: true }
)
tableStore.table.params.powerFlag = "0"
tableStore.table.params.isUpToGrid = 0
tableStore.table.params.type = 1
// 监听统计类型变化同步更新ids
const handleStatisticalTypeChange = (newVal: { id: any }) => {
console.log("统计类型变化", newVal)
if (newVal) {
tableStore.table.params.ids = [newVal.id]
// 根据统计类型动态更新标题
if (newVal.name) {
harmonicValueTitle.value = newVal.name + '污染值'
}
}
// 重新调用接口
tableStore.index()
}
// 处理过滤条件变化
const handleFilterChange = () => {
// 更新本地电网标志值
localFilters.powerFlag = tableStore.table.params.powerFlag
// 重置分页到第一页
tableStore.table.params.pageNum = 1
// 更新数据和总条数
tableStore.table.data = currentPageData.value
tableStore.table.total = updateTotal.value
}
// 分页事件处理
const handleSizeChange = (val: number) => {
tableStore.table.params.pageSize = val
tableStore.table.params.pageNum = 1
tableStore.table.data = currentPageData.value
tableStore.table.total = updateTotal.value
}
const handleCurrentChange = (val: number) => {
tableStore.table.params.pageNum = val
tableStore.table.data = currentPageData.value
tableStore.table.total = updateTotal.value
}
// 导出
const exportEvent = () => {
// 获取当前过滤后的所有数据
const allFilteredData = filteredData.value;
// 使用 vxe-table 的导出功能
positioningtableRef.value.exportData({
filename: '谐波电压污染报告',
sheetName: 'Sheet1',
type: 'xlsx',
useStyle: true,
data: allFilteredData,
columnFilterMethod: function (column, $columnIndex) {
return !(column.$columnIndex === 0)
}
})
}
onMounted(() => {
tableStore.index()
TableHeaderRef.value?.setDatePicker([
{ label: '年份', value: 1 },
{ label: '季度', value: 2 },
{ label: '月份', value: 3 },
{ label: '周', value: 4 }
])
calculateTableHeight()
window.addEventListener('resize', debouncedCalculateTableHeight)
})
onBeforeUnmount(() => {
window.removeEventListener('resize', debouncedCalculateTableHeight)
})
</script>
<style scoped lang="scss">
.full-height {
/* 使用视口高度确保占满整个屏幕 */
height: 91vh;
display: flex;
flex-direction: column;
}
.table-container {
flex: 1;
display: flex;
flex-direction: column;
/* 关键:隐藏容器的滚动条 */
overflow: hidden;
}
.full-height-table {
flex: 1;
/* 关键:只允许表格内容滚动 */
overflow: hidden;
}
:deep .vxe-table {
/* 确保表格组件本身可以滚动 */
height: 100% !important;
overflow: hidden !important;
}
:deep .vxe-table--body-wrapper {
/* 关键:确保表格主体可以滚动 */
overflow: auto !important;
}
.pagination-container {
display: flex;
justify-content: space-between; /* 左右分布 */
align-items: center;
min-height: 60px; /* 使用最小高度而不是固定高度 */
padding: 10px 20px; /* 增加左右内边距 */
}
:deep .el-pagination {
display: flex;
align-items: center;
width: 100%; /* 占满容器宽度 */
.el-pagination__sizes {
.el-select {
min-width: 128px;
}
}
.el-pagination__total {
margin-right: 10px;
}
/* 将除了 sizes 和 total 之外的所有元素都推到最右边 */
.btn-prev,
.btn-pager,
.btn-next,
.el-pagination__jump {
margin-left: auto;
}
/* 确保这些元素之间有适当的间距 */
.btn-prev {
margin-right: 5px;
}
.btn-next {
margin-left: 5px;
}
.el-pagination__jump {
margin-left: 10px;
}
}
</style>