| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <script setup lang="ts">
- import {
- NCard,
- NTag,
- NButton,
- NIcon,
- NGrid,
- NGi,
- NBadge,
- NImage,
- NSkeleton,
- NSpin,
- NFlex,
- NModal,
- } from "naive-ui";
- import { timeFormat } from "@/utils";
- import type { AlertItem } from "../Alert.vue";
- const props = defineProps<{ alertData: any[]; loading?: boolean }>();
- const drawerShow = ref(false);
- const currentItem = ref<AlertItem>(null);
- function getLabel(item: any) {
- if (Array.isArray(item.FieldList) && typeof item.Type === "number") {
- return item.FieldList[item.Type] || `类型-${item.Type}`;
- }
- return item.Type || "未知";
- }
- function formatScore(s: number | undefined) {
- if (s == null) return "-";
- return `${Math.round((s as number) * 100)}%`;
- }
- const drawerOpen = (item: any) => {
- currentItem.value = item;
- drawerShow.value = true;
- };
- defineExpose({
- drawerOpen,
- });
- </script>
- <template>
- <n-flex
- v-if="loading"
- class="absolute w-full h-full"
- justify="center"
- align="center"
- >
- <n-spin size="medium" />
- </n-flex>
- <n-grid v-else x-gap="20" y-gap="20" cols="1 s:2 m:4 l:4" responsive="screen">
- <n-gi v-for="item in props.alertData" :key="item.EventID || item.ID">
- <n-card
- hoverable
- content-style="padding: 0"
- class="border-white/5! rounded! overflow-hidden group hover:border-primary/50! transition-all duration-300"
- >
- <!-- 告警详情 -->
- <div class="p-4 space-y-2">
- <div class="flex justify-between items-center">
- <div>
- <h3 class="text-sm font-bold text-slate-100 line-clamp-1">
- {{ item.Alias }}
- </h3>
- </div>
- <span class="text-[12px] text-slate-400">
- {{ timeFormat(item.EventTime) || "-" }}
- </span>
- </div>
- <div
- class="grid grid-cols-2 gap-y-2 text-[11px] text-slate-500 font-mono"
- >
- <div class="flex items-center gap-1.5">
- <div class="i-token-zkid w-4 h-4 text-slate-600" />
- {{ item.ID ?? "-" }}
- </div>
- <div class="flex items-center justify-end gap-1.5">
- <div class="i-carbon-ip w-6 h-6 text-slate-600" />
- {{ item.EdgeIp ?? "-" }}
- </div>
- <div class="flex items-center gap-1.5 col-span-2">
- <div
- class="i-material-symbols-description-outline w-4 h-4 text-slate-600"
- />
- {{ item.Msg ?? "-" }}
- </div>
- </div>
- <div class="pt-2 flex gap-2">
- <n-button
- size="small"
- class="flex-1 rounded-md!"
- @click="drawerOpen(item)"
- >
- <template #icon><div class="i-lucide-file-text" /></template>
- 查看详情
- </n-button>
- <!-- <n-button
- size="small"
- type="error"
- class="flex-1 rounded-md!"
- ghost
- @click="console.log('详情', item)"
- >
- <template #icon><div class="i-lucide-delete" /></template>
- 删除
- </n-button> -->
- </div>
- </div>
- </n-card>
- </n-gi>
- </n-grid>
- <!-- <Drawer v-model="drawerShow" v-model:currentItem="currentItem">
- <AlarmShow />
- </Drawer> -->
- <n-modal
- v-model:show="drawerShow"
- :mask-closable="false"
- preset="dialog"
- title="查看详情"
- :showIcon="false"
- negative-text="关闭"
- @negative-click="drawerShow = false"
- >
- <n-flex vertical>
- <div>
- <span class="inline-block w-50px">ID :</span>
- <span>{{ currentItem.ID }}</span>
- </div>
- <div>
- <span class="inline-block w-50px">设备 :</span>
- <span>{{ currentItem.Alias }}</span>
- </div>
- <div>
- <span class="inline-block w-50px">时间 :</span>
- <span>{{ timeFormat(currentItem.EventTime) }}</span>
- </div>
- <div>
- <span class="inline-block w-50px">IP :</span>
- <span>{{ currentItem.EdgeIp }}</span>
- </div>
- <div>
- <span class="inline-block w-50px">描述 :</span>
- <span>{{ currentItem.Msg }}</span>
- </div>
- </n-flex>
- </n-modal>
- </template>
|