|
|
|
|
@ -67,16 +67,12 @@
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="onlineStatus" label="在线状态" width="100" align="center">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-tag :type="row.onlineStatus === '1' ? 'success' : 'info'" size="small">
|
|
|
|
|
{{ row.onlineStatus === '1' ? '在线' : '离线' }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
<dict-tag :options="online_status" :value="row.onlineStatus"/>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="alarmStatus" label="告警状态" width="100" align="center">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-tag :type="row.alarmStatus === '1' ? 'danger' : 'success'" size="small">
|
|
|
|
|
{{ row.alarmStatus === '1' ? '告警' : '正常' }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
<dict-tag :options="alarm_status" :value="row.alarmStatus"/>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
@ -93,16 +89,14 @@
|
|
|
|
|
<el-table :data="alarmList" border stripe max-height="400" empty-text="暂无数据">
|
|
|
|
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
|
|
|
|
<el-table-column prop="deviceName" label="设备" min-width="100">
|
|
|
|
|
<template #default="{ row }">{{ row.deviceName || row.deviceCode || '-' }}</template>
|
|
|
|
|
<template #default="{ row }">{{ row.deviceName || '-' }}</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="recordTime" label="时间" min-width="140">
|
|
|
|
|
<template #default="{ row }">{{ formatRecordTime(row.recordTime) }}</template>
|
|
|
|
|
<el-table-column prop="alarmTime" label="时间" min-width="140">
|
|
|
|
|
<template #default="{ row }">{{ row.alarmTime || '-' }}</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="alarmLevel" label="级别" width="80" align="center">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<el-tag :type="row.alarmLevel === '2' ? 'danger' : 'warning'" size="small">
|
|
|
|
|
{{ row.alarmLevel === '2' ? '严重' : (row.alarmLevel === '1' ? '一般' : '-') }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
<dict-tag :options="alarm_level" :value="row.alarmLevel"/>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="alarmAction" label="行为" min-width="80">
|
|
|
|
|
@ -116,11 +110,13 @@
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup name="Index" lang="ts">
|
|
|
|
|
import { getDashboardStats } from "@/api/rfid/dashboard";
|
|
|
|
|
import { getRfidDeviceList } from "@/api/rfid/rfidDevice";
|
|
|
|
|
import { getRfidReadRecordList } from "@/api/rfid/rfidReadRecord";
|
|
|
|
|
import type { RfidDeviceVO } from "@/api/rfid/rfidDevice/types";
|
|
|
|
|
import type { RfidReadRecordVO } from "@/api/rfid/rfidReadRecord/types";
|
|
|
|
|
import { getRealtimeStats, getLocationTree } from "@/api/rfid/dashboard";
|
|
|
|
|
import type { LocationTreeNode, AlarmStatVO } from "@/api/rfid/dashboard/types";
|
|
|
|
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
|
|
const { online_status, alarm_status, alarm_level } = toRefs<any>(
|
|
|
|
|
proxy?.useDict("online_status", "alarm_status", "alarm_level")
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const stats = ref({
|
|
|
|
|
totalDevices: 0,
|
|
|
|
|
@ -128,16 +124,43 @@ const stats = ref({
|
|
|
|
|
offlineDevices: 0,
|
|
|
|
|
alarmDevices: 0
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const deviceList = ref<LocationTreeNode[]>([]);
|
|
|
|
|
const alarmList = ref<AlarmStatVO[]>([]);
|
|
|
|
|
|
|
|
|
|
const deviceList = ref<RfidDeviceVO[]>([]);
|
|
|
|
|
const alarmList = ref<RfidReadRecordVO[]>([]);
|
|
|
|
|
/**
|
|
|
|
|
* 从位置树中提取设备节点列表(locationType = '3' 且存在 deviceId)
|
|
|
|
|
*/
|
|
|
|
|
const extractDeviceList = (nodes: LocationTreeNode[] = []): LocationTreeNode[] => {
|
|
|
|
|
const result: LocationTreeNode[] = [];
|
|
|
|
|
const stack: LocationTreeNode[] = [...nodes];
|
|
|
|
|
|
|
|
|
|
while (stack.length > 0) {
|
|
|
|
|
const node = stack.pop() as LocationTreeNode;
|
|
|
|
|
if (node.children && node.children.length > 0) {
|
|
|
|
|
stack.push(...node.children);
|
|
|
|
|
}
|
|
|
|
|
if (node.locationType === "3" && node.deviceId != null) {
|
|
|
|
|
result.push(node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const loadStats = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getDashboardStats();
|
|
|
|
|
if (res.data) {
|
|
|
|
|
stats.value = res.data;
|
|
|
|
|
const res = await getRealtimeStats();
|
|
|
|
|
const data = res.data;
|
|
|
|
|
if (data && data.overview) {
|
|
|
|
|
stats.value = {
|
|
|
|
|
totalDevices: data.overview.deviceTotal ?? 0,
|
|
|
|
|
onlineDevices: data.overview.onlineCount ?? 0,
|
|
|
|
|
offlineDevices: data.overview.offlineCount ?? 0,
|
|
|
|
|
alarmDevices: data.overview.alarmCount ?? 0
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
alarmList.value = data?.alarmStats || [];
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("获取统计数据失败", e);
|
|
|
|
|
}
|
|
|
|
|
@ -145,33 +168,17 @@ const loadStats = async () => {
|
|
|
|
|
|
|
|
|
|
const loadDeviceList = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res: any = await getRfidDeviceList({ isMarked: "1" } as any);
|
|
|
|
|
deviceList.value = res.data || [];
|
|
|
|
|
const res = await getLocationTree();
|
|
|
|
|
const tree = res.data || [];
|
|
|
|
|
deviceList.value = extractDeviceList(tree);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("获取设备列表失败", e);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const loadAlarmList = async () => {
|
|
|
|
|
try {
|
|
|
|
|
const res: any = await getRfidReadRecordList({ alarmFlag: "1" } as any);
|
|
|
|
|
alarmList.value = res.data || [];
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("获取告警记录失败", e);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const formatRecordTime = (val: any) => {
|
|
|
|
|
if (!val) {
|
|
|
|
|
return "-";
|
|
|
|
|
}
|
|
|
|
|
return String(val).replace("T", " ");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
loadStats();
|
|
|
|
|
loadDeviceList();
|
|
|
|
|
loadAlarmList();
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|