VueStructData.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <script setup lang="ts">
  2. import { ref, onMounted, computed } from 'vue'
  3. import { ElMessage } from 'element-plus'
  4. import { Download, Grid, TrendCharts, BarChart } from '@element-plus/icons-vue'
  5. import assist from '/@/api/assist'
  6. import { useLoading } from '/@/utils/loading-util'
  7. import VueCharts from './VueCharts.vue'
  8. import download from 'downloadjs'
  9. const props = defineProps<{
  10. uuid: string
  11. }>()
  12. // 定义数据结构类型
  13. interface StructData {
  14. fields: string[]
  15. data: { [key: string]: string }[]
  16. }
  17. const data = ref<StructData>()
  18. const { loading: loadingStruct, doLoading: doLoadingStruct } = useLoading(async () => {
  19. data.value = await assist.struct(props.uuid)
  20. })
  21. // 导出数据为CSV格式
  22. const exportToCSV = () => {
  23. if (!data.value || !data.value.fields || !data.value.data) {
  24. ElMessage.warning('暂无数据可导出')
  25. return
  26. }
  27. try {
  28. // 构建CSV内容
  29. const headers = data.value.fields.map((it) => `"${it}"`).join(',')
  30. const rows = data.value.data.map(rowJson => {
  31. return data.value!.fields.map(field => `"${rowJson[field]}"`).join(',')
  32. })
  33. const csvContent = [headers, ...rows].join('\n')
  34. download(csvContent, 'export.csv', 'text/csv,charset=utf-8;')
  35. ElMessage.success('数据导出成功')
  36. } catch (error) {
  37. console.error('导出失败:', error)
  38. ElMessage.error('导出失败,请重试')
  39. }
  40. }
  41. // 组件挂载时加载数据
  42. onMounted(doLoadingStruct)
  43. const display = ref<'table' | 'bar' | 'line'>('table')
  44. const barChart = ref()
  45. const lineChart = ref()
  46. </script>
  47. <template>
  48. <div class="struct-data-container">
  49. <el-card v-loading="loadingStruct" shadow="none" :body-style="{ padding: 0, margin: 0 }">
  50. <template #header>
  51. <div class="card-header">
  52. <span>结构化数据表格</span>
  53. <el-popover placement="top" :width="120" trigger="hover" content="导出为CSV文件">
  54. <template #reference>
  55. <el-button
  56. :icon="Download"
  57. size="small"
  58. text
  59. circle
  60. @click="exportToCSV"
  61. :disabled="!data || !data.fields || !data.data || data.data.length === 0"
  62. class="export-btn"
  63. />
  64. </template>
  65. </el-popover>
  66. </div>
  67. </template>
  68. <!-- 表格内容 -->
  69. <div v-if="data && data.fields && data.data" class="table-wrapper">
  70. <el-table :data="data.data" stripe border size="small" max-height="400">
  71. <el-table-column v-for="field in data.fields" :key="field" :prop="field" :label="field" align="center" min-width="120">
  72. <template #default="{ row }">
  73. <span>{{ row[field] || '-' }}</span>
  74. </template>
  75. </el-table-column>
  76. </el-table>
  77. </div>
  78. <!-- 空数据状态 -->
  79. <div v-else-if="!loadingStruct" class="empty-state">
  80. <el-empty description="暂无数据" />
  81. </div>
  82. </el-card>
  83. </div>
  84. </template>
  85. <style scoped lang="scss">
  86. .struct-data-container {
  87. margin: 16px 0;
  88. .card-header {
  89. display: flex;
  90. justify-content: space-between;
  91. align-items: center;
  92. font-weight: 500;
  93. color: var(--el-text-color-primary);
  94. .export-btn {
  95. color: var(--el-color-primary);
  96. &:hover {
  97. background-color: var(--el-color-primary-light-9);
  98. }
  99. &:disabled {
  100. color: var(--el-text-color-disabled);
  101. cursor: not-allowed;
  102. }
  103. }
  104. }
  105. .table-wrapper {
  106. .el-table {
  107. overflow: hidden;
  108. }
  109. }
  110. .empty-state {
  111. padding: 40px 0;
  112. text-align: center;
  113. }
  114. :deep(table) {
  115. margin: 0 !important;
  116. }
  117. }
  118. .el-card {
  119. background: transparent !important;
  120. }
  121. :deep(.el-table__cell) {
  122. background: transparent !important;
  123. }
  124. </style>