200 lines
5.8 KiB
Vue
200 lines
5.8 KiB
Vue
|
|
<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>
|