- 在补数任务面板中添加入库类型单选按钮组,支持 MySQL 和 InfluxDB - 更新 AddData 接口定义,添加 StorageType 相关类型和选项接口 - 修改补数 API 请求逻辑,根据入库类型动态调整接口路径前缀 - 重构台账设备表单,统一使用装置网络参数作为 MAC 和 NDID 的单一数据源 - 优化台账线路表单,仅当存在 ID 时才设置 lineId 字段,避免空值传递 - 添加入库类型列表获取接口和相关数据处理逻辑 - 更新台账字典代码常量,新增终端型号字典码 - 优化台账树节点添加逻辑,增加前置条件验证和禁用原因提示 - 添加 InfluxDB 配置文件到额外资源目录 - 更新稳定数据分析视图,优化台账树数据结构处理和样式布局 - 完善 API 调试契约检查,确保设备和线路数据映射正确性 - 优化趋势查询性能,禁用全局加载状态提升用户体验
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>
|