Files
CN_Tool_client/frontend/src/views/steady/steadyDataView/components/SteadyTrendDataTableDialog.vue

200 lines
5.8 KiB
Vue
Raw Normal View History

<template>
<el-dialog
v-model="visibleProxy"
class="steady-trend-data-dialog"
title="数据查询"
width="86vw"
top="7vh"
append-to-body
destroy-on-close
>
<div class="table-main card steady-trend-data-table">
<div class="table-header">
<div class="header-button-lf">
<el-button
type="primary"
:icon="Download"
plain
:loading="downloading"
:disabled="!tableModel.timeValues.length"
@click="downloadSteadyTrendData"
>
下载数据
</el-button>
</div>
<div class="header-button-ri"></div>
</div>
<el-table :data="pagedRows" border stripe height="100%">
<el-table-column prop="time" label="时间" min-width="170" fixed="left" align="center" />
<el-table-column
v-for="lineGroup in tableModel.lineGroups"
:key="lineGroup.key"
:label="lineGroup.label"
align="center"
>
<el-table-column
v-for="indicatorGroup in lineGroup.indicatorGroups"
:key="indicatorGroup.key"
:label="indicatorGroup.label"
align="center"
>
<el-table-column
v-for="column in indicatorGroup.columns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
min-width="110"
align="center"
>
<template #default="{ row }">
{{ row[column.prop] ?? '-' }}
</template>
</el-table-column>
</el-table-column>
</el-table-column>
</el-table>
<div class="table-footer">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
background
layout="total, sizes, prev, pager, next, jumper"
:page-sizes="[500, 1000, 2000, 5000]"
:total="tableModel.timeValues.length"
@size-change="currentPage = 1"
/>
</div>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { Download } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import type { SteadyDataView } from '@/api/steady/steadyDataView/interface'
import {
buildSteadyTrendExcelHtml,
buildSteadyTrendTableModel,
buildSteadyTrendTableRows,
createEmptySteadyTrendTableModel
} from '../utils/trendTable'
defineOptions({
name: 'SteadyTrendDataTableDialog'
})
const props = defineProps<{
modelValue: boolean
trendResult: SteadyDataView.SteadyTrendQueryResult | null
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
}>()
const currentPage = ref(1)
const pageSize = ref(500)
const downloading = ref(false)
const tableModel = shallowRef(createEmptySteadyTrendTableModel())
const visibleProxy = computed({
get: () => props.modelValue,
set: value => emit('update:modelValue', value)
})
const pagedRows = computed(() =>
buildSteadyTrendTableRows(tableModel.value, (currentPage.value - 1) * pageSize.value, pageSize.value)
)
const downloadSteadyTrendData = async () => {
if (!tableModel.value.timeValues.length || !tableModel.value.columns.length) {
ElMessage.warning('暂无可下载的数据')
return
}
downloading.value = true
try {
await nextTick()
const excelContent = buildSteadyTrendExcelHtml(tableModel.value)
const blob = new Blob([excelContent], { type: 'application/vnd.ms-excel;charset=utf-8;' })
const blobUrl = URL.createObjectURL(blob)
const exportFile = document.createElement('a')
exportFile.style.display = 'none'
exportFile.download = `steady-trend-data-${Date.now()}.xls`
exportFile.href = blobUrl
document.body.appendChild(exportFile)
exportFile.click()
document.body.removeChild(exportFile)
URL.revokeObjectURL(blobUrl)
ElMessage.success('数据下载成功')
} finally {
downloading.value = false
}
}
watch(
() => props.modelValue,
visible => {
if (visible) {
tableModel.value = buildSteadyTrendTableModel(props.trendResult?.series || [])
currentPage.value = 1
return
}
// 弹窗关闭后释放当前页表格模型,避免大数据量结果长期占用额外内存。
tableModel.value = createEmptySteadyTrendTableModel()
}
)
</script>
<style scoped lang="scss">
.steady-trend-data-table {
display: flex;
flex-direction: column;
height: 70vh;
min-height: 0;
padding: 12px;
overflow: hidden;
}
.table-header {
display: flex;
flex: none;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 10px;
}
.header-button-lf,
.header-button-ri {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.header-button-ri {
flex-shrink: 0;
}
.steady-trend-data-table :deep(.el-table) {
flex: 1;
min-height: 0;
}
.steady-trend-data-table :deep(.el-table__inner-wrapper) {
height: 100%;
}
.table-footer {
display: flex;
flex: none;
justify-content: flex-end;
padding-top: 10px;
}
</style>