123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <script setup lang="ts">
- import { ref, onMounted, computed } from 'vue'
- import { ElMessage } from 'element-plus'
- import { Download, Grid, TrendCharts, BarChart } from '@element-plus/icons-vue'
- import assist from '/@/api/assist'
- import { useLoading } from '/@/utils/loading-util'
- import VueCharts from './VueCharts.vue'
- import download from 'downloadjs'
- const props = defineProps<{
- uuid: string
- }>()
- // 定义数据结构类型
- interface StructData {
- fields: string[]
- data: { [key: string]: string }[]
- }
- const data = ref<StructData>()
- const { loading: loadingStruct, doLoading: doLoadingStruct } = useLoading(async () => {
- data.value = await assist.struct(props.uuid)
- })
- // 导出数据为CSV格式
- const exportToCSV = () => {
- if (!data.value || !data.value.fields || !data.value.data) {
- ElMessage.warning('暂无数据可导出')
- return
- }
- try {
- // 构建CSV内容
- const headers = data.value.fields.map((it) => `"${it}"`).join(',')
- const rows = data.value.data.map(rowJson => {
- return data.value!.fields.map(field => `"${rowJson[field]}"`).join(',')
- })
- const csvContent = [headers, ...rows].join('\n')
- download(csvContent, 'export.csv', 'text/csv,charset=utf-8;')
- ElMessage.success('数据导出成功')
- } catch (error) {
- console.error('导出失败:', error)
- ElMessage.error('导出失败,请重试')
- }
- }
- // 组件挂载时加载数据
- onMounted(doLoadingStruct)
- const display = ref<'table' | 'bar' | 'line'>('table')
- const barChart = ref()
- const lineChart = ref()
- </script>
- <template>
- <div class="struct-data-container">
- <el-card v-loading="loadingStruct" shadow="none" :body-style="{ padding: 0, margin: 0 }">
- <template #header>
- <div class="card-header">
- <span>结构化数据表格</span>
- <el-popover placement="top" :width="120" trigger="hover" content="导出为CSV文件">
- <template #reference>
- <el-button
- :icon="Download"
- size="small"
- text
- circle
- @click="exportToCSV"
- :disabled="!data || !data.fields || !data.data || data.data.length === 0"
- class="export-btn"
- />
- </template>
- </el-popover>
- </div>
- </template>
- <!-- 表格内容 -->
- <div v-if="data && data.fields && data.data" class="table-wrapper">
- <el-table :data="data.data" stripe border size="small" max-height="400">
- <el-table-column v-for="field in data.fields" :key="field" :prop="field" :label="field" align="center" min-width="120">
- <template #default="{ row }">
- <span>{{ row[field] || '-' }}</span>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <!-- 空数据状态 -->
- <div v-else-if="!loadingStruct" class="empty-state">
- <el-empty description="暂无数据" />
- </div>
- </el-card>
- </div>
- </template>
- <style scoped lang="scss">
- .struct-data-container {
- margin: 16px 0;
- .card-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-weight: 500;
- color: var(--el-text-color-primary);
- .export-btn {
- color: var(--el-color-primary);
- &:hover {
- background-color: var(--el-color-primary-light-9);
- }
- &:disabled {
- color: var(--el-text-color-disabled);
- cursor: not-allowed;
- }
- }
- }
- .table-wrapper {
- .el-table {
- overflow: hidden;
- }
- }
- .empty-state {
- padding: 40px 0;
- text-align: center;
- }
- :deep(table) {
- margin: 0 !important;
- }
- }
- .el-card {
- background: transparent !important;
- }
- :deep(.el-table__cell) {
- background: transparent !important;
- }
- </style>
|