gridData.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <script setup lang="ts">
  2. import {
  3. NCard,
  4. NTag,
  5. NButton,
  6. NIcon,
  7. NGrid,
  8. NGi,
  9. NBadge,
  10. NImage,
  11. NSkeleton,
  12. NSpin,
  13. NFlex,
  14. NModal,
  15. } from "naive-ui";
  16. import { timeFormat } from "@/utils";
  17. import type { AlertItem } from "../Alert.vue";
  18. const props = defineProps<{ alertData: any[]; loading?: boolean }>();
  19. const drawerShow = ref(false);
  20. const currentItem = ref<AlertItem>(null);
  21. function getLabel(item: any) {
  22. if (Array.isArray(item.FieldList) && typeof item.Type === "number") {
  23. return item.FieldList[item.Type] || `类型-${item.Type}`;
  24. }
  25. return item.Type || "未知";
  26. }
  27. function formatScore(s: number | undefined) {
  28. if (s == null) return "-";
  29. return `${Math.round((s as number) * 100)}%`;
  30. }
  31. const drawerOpen = (item: any) => {
  32. currentItem.value = item;
  33. drawerShow.value = true;
  34. };
  35. defineExpose({
  36. drawerOpen,
  37. });
  38. </script>
  39. <template>
  40. <n-flex
  41. v-if="loading"
  42. class="absolute w-full h-full"
  43. justify="center"
  44. align="center"
  45. >
  46. <n-spin size="medium" />
  47. </n-flex>
  48. <n-grid v-else x-gap="20" y-gap="20" cols="1 s:2 m:4 l:4" responsive="screen">
  49. <n-gi v-for="item in props.alertData" :key="item.EventID || item.ID">
  50. <n-card
  51. hoverable
  52. content-style="padding: 0"
  53. class="border-white/5! rounded! overflow-hidden group hover:border-primary/50! transition-all duration-300"
  54. >
  55. <!-- 告警详情 -->
  56. <div class="p-4 space-y-2">
  57. <div class="flex justify-between items-center">
  58. <div>
  59. <h3 class="text-sm font-bold text-slate-100 line-clamp-1">
  60. {{ item.Alias }}
  61. </h3>
  62. </div>
  63. <span class="text-[12px] text-slate-400">
  64. {{ timeFormat(item.EventTime) || "-" }}
  65. </span>
  66. </div>
  67. <div
  68. class="grid grid-cols-2 gap-y-2 text-[11px] text-slate-500 font-mono"
  69. >
  70. <div class="flex items-center gap-1.5">
  71. <div class="i-token-zkid w-4 h-4 text-slate-600" />
  72. {{ item.ID ?? "-" }}
  73. </div>
  74. <div class="flex items-center justify-end gap-1.5">
  75. <div class="i-carbon-ip w-6 h-6 text-slate-600" />
  76. {{ item.EdgeIp ?? "-" }}
  77. </div>
  78. <div class="flex items-center gap-1.5 col-span-2">
  79. <div
  80. class="i-material-symbols-description-outline w-4 h-4 text-slate-600"
  81. />
  82. {{ item.Msg ?? "-" }}
  83. </div>
  84. </div>
  85. <div class="pt-2 flex gap-2">
  86. <n-button
  87. size="small"
  88. class="flex-1 rounded-md!"
  89. @click="drawerOpen(item)"
  90. >
  91. <template #icon><div class="i-lucide-file-text" /></template>
  92. 查看详情
  93. </n-button>
  94. <!-- <n-button
  95. size="small"
  96. type="error"
  97. class="flex-1 rounded-md!"
  98. ghost
  99. @click="console.log('详情', item)"
  100. >
  101. <template #icon><div class="i-lucide-delete" /></template>
  102. 删除
  103. </n-button> -->
  104. </div>
  105. </div>
  106. </n-card>
  107. </n-gi>
  108. </n-grid>
  109. <!-- <Drawer v-model="drawerShow" v-model:currentItem="currentItem">
  110. <AlarmShow />
  111. </Drawer> -->
  112. <n-modal
  113. v-model:show="drawerShow"
  114. :mask-closable="false"
  115. preset="dialog"
  116. title="查看详情"
  117. :showIcon="false"
  118. negative-text="关闭"
  119. @negative-click="drawerShow = false"
  120. >
  121. <n-flex vertical>
  122. <div>
  123. <span class="inline-block w-50px">ID :</span>
  124. <span>{{ currentItem.ID }}</span>
  125. </div>
  126. <div>
  127. <span class="inline-block w-50px">设备 :</span>
  128. <span>{{ currentItem.Alias }}</span>
  129. </div>
  130. <div>
  131. <span class="inline-block w-50px">时间 :</span>
  132. <span>{{ timeFormat(currentItem.EventTime) }}</span>
  133. </div>
  134. <div>
  135. <span class="inline-block w-50px">IP :</span>
  136. <span>{{ currentItem.EdgeIp }}</span>
  137. </div>
  138. <div>
  139. <span class="inline-block w-50px">描述 :</span>
  140. <span>{{ currentItem.Msg }}</span>
  141. </div>
  142. </n-flex>
  143. </n-modal>
  144. </template>