264 lines
10 KiB
Vue
264 lines
10 KiB
Vue
<template>
|
||
<el-dialog draggable width="1400px" class="cn-operate-dialog" v-model="dialogVisible" :title="title">
|
||
<div style="display: flex" v-loading="loading">
|
||
<div :style="height1" class="mr10 box" style="width: 550px">
|
||
<vxe-table
|
||
height="auto"
|
||
:data="TableData"
|
||
v-bind="defaultAttribute"
|
||
ref="tableRef"
|
||
:row-config="{ isCurrent: true, isHover: true }"
|
||
@current-change="currentChangeEvent"
|
||
>
|
||
<vxe-column type="seq" title="序号" width="60px"></vxe-column>
|
||
<!-- <vxe-column field="date" title="日期"></vxe-column> -->
|
||
<vxe-column field="bdName" title="所属电站(场站)"></vxe-column>
|
||
<vxe-column field="monitorName" title="监测点名称"></vxe-column>
|
||
<vxe-column field="timeSum" title="告警天数" width="80px">
|
||
<template v-slot="{ row }">
|
||
{{ row.dateTargetList?.length }}
|
||
</template>
|
||
</vxe-column>
|
||
</vxe-table>
|
||
</div>
|
||
|
||
<div style="width: 820px" v-loading="loading1">
|
||
<el-form :inline="true" class="form">
|
||
<el-form-item label="统计日期">
|
||
<el-select
|
||
v-model="timeList"
|
||
clearable
|
||
placeholder="请选择告警天数"
|
||
style="width: 180px"
|
||
@change="change"
|
||
>
|
||
<el-option
|
||
v-for="item in dateList"
|
||
:key="item.date"
|
||
:label="item.date"
|
||
:value="item.date"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="统计指标" v-if="numKey != 0">
|
||
<el-select
|
||
v-model="targetKey"
|
||
filterable
|
||
clearable
|
||
placeholder="请选择指标"
|
||
style="width: 150px"
|
||
>
|
||
<el-option
|
||
v-for="item in targetList"
|
||
:key="item.key"
|
||
:label="item.targetName"
|
||
:value="item.key"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item class="form_but">
|
||
<span class="mr20">
|
||
告警时间:
|
||
<span class="title">{{ timeSum }}</span>
|
||
分钟
|
||
</span>
|
||
|
||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div :style="height">
|
||
<vxe-table
|
||
height="auto"
|
||
:data="TableData1?.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
|
||
v-bind="defaultAttribute"
|
||
>
|
||
<vxe-column type="seq" title="序号" width="80px">
|
||
<template #default="{ rowIndex }">
|
||
<span>{{ (pageNum - 1) * pageSize + rowIndex + 1 }}</span>
|
||
</template>
|
||
</vxe-column>
|
||
<vxe-column field="time" width="150px" title="时间" :formatter="formatter"></vxe-column>
|
||
<vxe-column field="targetName" title="指标类型" min-width="100px"></vxe-column>
|
||
<vxe-column field="phaseType" title="相别" width="80px">
|
||
<template v-slot="{ row }">
|
||
{{ row.phaseType == 'T' ? '/' : row.phaseType }}
|
||
</template>
|
||
</vxe-column>
|
||
|
||
<vxe-column field="type" title="数据类型" width="105px" :formatter="formatter"></vxe-column>
|
||
<vxe-column field="val" title="值" width="85px" :formatter="formatter"></vxe-column>
|
||
<vxe-column
|
||
field="overLimitValue"
|
||
title="限值"
|
||
width="85px"
|
||
:formatter="formatter"
|
||
></vxe-column>
|
||
</vxe-table>
|
||
<div class="table-pagination">
|
||
<el-pagination
|
||
v-model:currentPage="pageNum"
|
||
v-model:page-size="pageSize"
|
||
:page-sizes="[10, 20, 50, 100, 200]"
|
||
background
|
||
layout="sizes,total, ->, prev, pager, next, jumper"
|
||
:total="TableData1?.length || 0"
|
||
></el-pagination>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-dialog>
|
||
</template>
|
||
<script lang="ts" setup>
|
||
import { ref, inject } from 'vue'
|
||
import { reactive } from 'vue'
|
||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||
import { ElMessage } from 'element-plus'
|
||
import { monitorLimitTable, monitorLimitTableDetail } from '@/api/device-boot/dataVerify'
|
||
import { mainHeight } from '@/utils/layout'
|
||
const dialogVisible = ref(false)
|
||
const height1 = mainHeight(-110, 2)
|
||
const height = mainHeight(90, 2)
|
||
const tableRef = ref()
|
||
const title = ref('')
|
||
const loading = ref(false)
|
||
const loading1 = ref(false)
|
||
const TableData = ref([])
|
||
const TableData1 = ref([])
|
||
const dateList: any = ref([])
|
||
const pageNum = ref(1)
|
||
const pageSize = ref(20)
|
||
const numKey = ref(0)
|
||
const targetKey = ref('')
|
||
const targetList: any = ref([])
|
||
const timeSum = ref('')
|
||
const timeList = ref('')
|
||
const showColumn = ref(true)
|
||
|
||
const open = (data: anyObj, time: string[], num: number) => {
|
||
// title.value = (num == 0 ? data.targetName : data.monitorName) + '_告警监测点详情'
|
||
loading.value = true
|
||
title.value = '告警监测点详情'
|
||
TableData.value = []
|
||
numKey.value = num
|
||
targetKey.value = data.key || ''
|
||
monitorLimitTable({
|
||
monitorIds: num == 0 ? data.ids : [data.monitorId],
|
||
targetKey: num == 0 ? data.key : '',
|
||
searchBeginTime: time[0],
|
||
searchEndTime: time[1]
|
||
})
|
||
.then(async res => {
|
||
TableData.value = res.data
|
||
await tableRef.value.setCurrentRow(TableData.value[0])
|
||
await currentChangeEvent()
|
||
loading.value = false
|
||
})
|
||
.catch(() => {
|
||
loading.value = false
|
||
})
|
||
dialogVisible.value = true
|
||
}
|
||
const currentChangeEvent = () => {
|
||
let data = tableRef.value.getCurrentRecord()
|
||
|
||
dateList.value = data.dateTargetList
|
||
targetList.value = dateList.value[0].targetKeys
|
||
timeList.value = data.dateTargetList[0].date
|
||
|
||
init()
|
||
}
|
||
const init = () => {
|
||
if (timeList.value == '') return ElMessage.warning('请选择告警天数!')
|
||
loading1.value = true
|
||
TableData1.value = []
|
||
let data = tableRef.value.getCurrentRecord()
|
||
monitorLimitTableDetail({
|
||
monitorIds: [data.monitorId],
|
||
searchBeginTime: timeList.value,
|
||
targetKey: targetKey.value || '' //numKey.value == 0 ? targetKey.value : ''
|
||
})
|
||
.then(res => {
|
||
timeSum.value = res.data.timeSum
|
||
TableData1.value = res.data.time
|
||
showColumn.value = res.data[0]?.featureAmplitude == null ? true : false
|
||
loading1.value = false
|
||
pageNum.value = 1
|
||
})
|
||
.catch(() => {
|
||
loading1.value = false
|
||
})
|
||
}
|
||
const change = () => {
|
||
if (timeList.value == '') targetKey.value = ''
|
||
let list = dateList.value
|
||
.filter(item => timeList.value == item.date)
|
||
?.map(item => {
|
||
return item.targetKeys
|
||
})
|
||
.flat()
|
||
targetList.value = deduplicateByKey(list)
|
||
if (!targetList.value.some(item => item.key == targetKey.value) ) {
|
||
targetKey.value = ''
|
||
}
|
||
// console.log('🚀 ~ change ~ targetList.value:', targetList.value)
|
||
}
|
||
// 核心去重逻辑
|
||
function deduplicateByKey(data) {
|
||
// 使用Map存储唯一key,保证顺序且去重
|
||
const uniqueMap = new Map()
|
||
data.forEach(item => {
|
||
if (!uniqueMap.has(item.key)) {
|
||
uniqueMap.set(item.key, item)
|
||
}
|
||
})
|
||
|
||
// 转换为数组并按sort排序
|
||
const deduplicatedData = Array.from(uniqueMap.values())
|
||
return deduplicatedData
|
||
}
|
||
const formatter = (row: any) => {
|
||
if (row.column.field == 'time') {
|
||
return timeList.value + ' ' + row.cellValue
|
||
} else if (row.column.field == 'type') {
|
||
return row.cellValue === 'null' ? '/' : row.cellValue
|
||
} else {
|
||
return row.cellValue == null ? '/' : (row.cellValue - 0).toFixed(2)
|
||
}
|
||
}
|
||
defineExpose({ open })
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
.table-pagination {
|
||
height: 58px;
|
||
box-sizing: border-box;
|
||
width: 100%;
|
||
max-width: 100%;
|
||
background-color: var(--ba-bg-color-overlay);
|
||
padding: 13px 15px;
|
||
border-left: 1px solid #e4e7e9;
|
||
border-right: 1px solid #e4e7e9;
|
||
border-bottom: 1px solid #e4e7e9;
|
||
}
|
||
:deep(.box) {
|
||
.row--current {
|
||
// background-color: var(--el-color-primary-light-8) !important;
|
||
}
|
||
}
|
||
.form {
|
||
position: relative;
|
||
.form_but {
|
||
position: absolute;
|
||
right: -22px;
|
||
}
|
||
}
|
||
.title {
|
||
font-weight: 600;
|
||
font-size: 16px;
|
||
}
|
||
:deep(.el-select) {
|
||
min-width: 100px !important;
|
||
}
|
||
</style>
|