index.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <a-skeleton active :loading="loading">
  3. <div class="table" v-show="showTable">
  4. <vxe-toolbar v-if="!isTemplate">
  5. <template #tools>
  6. <vxe-button @click="exportData" class="icons-list" style="width: 40px;">
  7. <a-icon type="download" />
  8. </vxe-button>
  9. </template>
  10. </vxe-toolbar>
  11. <vxe-grid
  12. v-bind="gridProps"
  13. size="mini"
  14. border
  15. resizable
  16. ref="overviewTable"
  17. :columns="columns"
  18. :scroll-x="{enabled: false}"
  19. :data="tableRows">
  20. <template v-slot:empty>
  21. <loader :loading="loading" :noDataText="$t('common.notData')" />
  22. </template>
  23. </vxe-grid>
  24. <div style="visibility: hidden;height:1px;overflow:hidden;">
  25. <vxe-grid
  26. ref="overviewTable2"
  27. :columns="columns2"
  28. max-height="1"
  29. :data="tableRows" />
  30. </div>
  31. <div v-if="showTotal" class="vxe-grid--pager-wrapper">
  32. <div class="vxe-pager size--mini">
  33. <div class="vxe-pager--wrapper">
  34. <span class="vxe-pager--total">{{ total }}</span>
  35. </div>
  36. </div>
  37. </div>
  38. </div>
  39. </a-skeleton>
  40. </template>
  41. <script>
  42. export default {
  43. name: 'OverviewTable',
  44. props: {
  45. loading: {
  46. type: Boolean,
  47. default: false,
  48. },
  49. tableData: {
  50. type: Object,
  51. default: () => ({}),
  52. },
  53. isTemplate: {
  54. type: Boolean,
  55. default: false,
  56. },
  57. fucType: {
  58. type: Array,
  59. default: () => [],
  60. },
  61. },
  62. computed: {
  63. showTable () {
  64. return this.tableData && this.tableData.rows
  65. },
  66. total () {
  67. if (this.showTable) {
  68. return this.$t('monitor_metric_78', [this.tableData.rows.length])
  69. }
  70. return 0
  71. },
  72. columns () {
  73. let cols = (this.tableData?.columns || []).filter(item => !item.onlyExport)
  74. // isTemplate 时根据 fucType 生成指标列
  75. if (this.isTemplate && cols.length > 0 && this.fucType && this.fucType.length > 0) {
  76. // 识别非指标列(name、IP 等固定列)
  77. const nonMetricFields = ['color', 'name', 'vm_name', 'host', 'rds_name', 'tenant', 'project_domain', 'system', 'brand', 'cloudregion', 'zone', 'external_id', 'id', 'internal_connection_str', 'connection_str', 'all_ip', 'elastic_ip', 'ip', 'raw_name']
  78. // 找出所有指标列(非固定列)
  79. const metricColumns = cols.filter(col => !nonMetricFields.includes(col.field))
  80. // 保留非指标列
  81. const nonMetricCols = cols.filter(col => nonMetricFields.includes(col.field))
  82. if (metricColumns.length > 0) {
  83. const firstMetricColumn = metricColumns[0]
  84. // 根据 fucType 生成新的指标列
  85. const newMetricCols = this.fucType.map(fucType => {
  86. const fucTypeLabel = this.$t(`common.${fucType}`)
  87. return {
  88. ...firstMetricColumn,
  89. field: `${firstMetricColumn.field}_${fucType}`,
  90. title: `${firstMetricColumn.title} - ${fucTypeLabel}`,
  91. }
  92. })
  93. cols = [...nonMetricCols, ...newMetricCols]
  94. }
  95. } else if (this.isTemplate && cols.length > 0) {
  96. // 如果没有 fucType,保持原有逻辑:只保留第一个指标列
  97. const nonMetricFields = ['color', 'name', 'vm_name', 'host', 'rds_name', 'tenant', 'project_domain', 'system', 'brand', 'cloudregion', 'zone', 'external_id', 'id', 'internal_connection_str', 'connection_str', 'all_ip', 'elastic_ip', 'ip', 'raw_name']
  98. const metricColumns = cols.filter(col => !nonMetricFields.includes(col.field))
  99. if (metricColumns.length > 1) {
  100. const firstMetricColumn = metricColumns[0]
  101. cols = cols.filter(col => nonMetricFields.includes(col.field) || col.field === firstMetricColumn.field)
  102. }
  103. }
  104. // 模板模式下,不显示排序按钮
  105. if (this.isTemplate) {
  106. return cols.map(col => {
  107. return {
  108. ...col,
  109. sortable: false,
  110. }
  111. })
  112. }
  113. return cols
  114. },
  115. columns2 () {
  116. let cols = (this.tableData?.columns || []).filter(item => !item.noExport)
  117. // isTemplate 时根据 fucType 生成指标列
  118. if (this.isTemplate && cols.length > 0 && this.fucType && this.fucType.length > 0) {
  119. // 识别非指标列(name、IP 等固定列)
  120. const nonMetricFields = ['color', 'name', 'vm_name', 'host', 'rds_name', 'tenant', 'project_domain', 'system', 'brand', 'cloudregion', 'zone', 'external_id', 'id', 'internal_connection_str', 'connection_str', 'all_ip', 'elastic_ip', 'ip', 'raw_name']
  121. // 找出所有指标列(非固定列)
  122. const metricColumns = cols.filter(col => !nonMetricFields.includes(col.field))
  123. // 保留非指标列
  124. const nonMetricCols = cols.filter(col => nonMetricFields.includes(col.field))
  125. if (metricColumns.length > 0) {
  126. const firstMetricColumn = metricColumns[0]
  127. // 根据 fucType 生成新的指标列
  128. const newMetricCols = this.fucType.map(fucType => {
  129. const fucTypeLabel = this.$t(`common.${fucType}`)
  130. return {
  131. ...firstMetricColumn,
  132. field: `${firstMetricColumn.field}_${fucType}`,
  133. title: `${firstMetricColumn.title} - ${fucTypeLabel}`,
  134. }
  135. })
  136. cols = [...nonMetricCols, ...newMetricCols]
  137. }
  138. } else if (this.isTemplate && cols.length > 0) {
  139. // 如果没有 fucType,保持原有逻辑:只保留第一个指标列
  140. const nonMetricFields = ['color', 'name', 'vm_name', 'host', 'rds_name', 'tenant', 'project_domain', 'system', 'brand', 'cloudregion', 'zone', 'external_id', 'id', 'internal_connection_str', 'connection_str', 'all_ip', 'elastic_ip', 'ip', 'raw_name']
  141. const metricColumns = cols.filter(col => !nonMetricFields.includes(col.field))
  142. if (metricColumns.length > 1) {
  143. const firstMetricColumn = metricColumns[0]
  144. cols = cols.filter(col => nonMetricFields.includes(col.field) || col.field === firstMetricColumn.field)
  145. }
  146. }
  147. return cols
  148. },
  149. gridProps () {
  150. const ret = {}
  151. if (!this.isTemplate) {
  152. ret['max-height'] = this.heightLimit
  153. ret.class = 'mt-4'
  154. }
  155. return ret
  156. },
  157. tableRows () {
  158. if (!this.tableData || !this.tableData.rows) {
  159. return []
  160. }
  161. // toTableData 已经处理了 fucType 的数据,直接返回即可
  162. return this.tableData.rows
  163. },
  164. },
  165. methods: {
  166. exportData () {
  167. this.$refs.overviewTable2.exportData({
  168. type: 'csv',
  169. })
  170. },
  171. },
  172. }
  173. </script>
  174. <style scoped>
  175. .icons-list >>> .anticon {
  176. font-size: 16px;
  177. }
  178. </style>