140 lines
4.5 KiB
Vue
140 lines
4.5 KiB
Vue
<script setup lang="ts">
|
||
import { detailDeviceApi, probeDeviceApi, type NdmDeviceResultVO } from '@/apis';
|
||
import { DeviceType, DeviceTypeName, tryGetDeviceTypeVal, type DeviceTypeVal } from '@/enums';
|
||
import { useDeviceStore } from '@/stores';
|
||
import { useMutation } from '@tanstack/vue-query';
|
||
import { ApiOutlined, ReloadOutlined } from '@vicons/antd';
|
||
import { NButton, NCard, NFlex, NIcon, NTag, NTooltip } from 'naive-ui';
|
||
import { computed, toRefs } from 'vue';
|
||
|
||
const props = defineProps<{
|
||
stationCode: string;
|
||
device: NdmDeviceResultVO;
|
||
}>();
|
||
|
||
// const emit = defineEmits<{}>();
|
||
|
||
const { stationCode, device } = toRefs(props);
|
||
|
||
const type = computed(() => {
|
||
const deviceTypeVal = tryGetDeviceTypeVal(device.value.deviceType);
|
||
if (!deviceTypeVal) return '-';
|
||
return DeviceTypeName[deviceTypeVal];
|
||
});
|
||
const name = computed(() => device.value.name ?? '-');
|
||
const ipAddr = computed(() => device.value.ipAddress ?? '-');
|
||
const gbCode = computed(() => Reflect.get(device.value, 'gbCode') as string | undefined);
|
||
const status = computed(() => device.value.deviceStatus);
|
||
|
||
const canOpenMgmtPage = computed(() => {
|
||
const mgmtableDeviceTypes: DeviceTypeVal[] = [DeviceType['Camera'], DeviceType['Decoder'], DeviceType['Switch']];
|
||
const deviceTypeVal = tryGetDeviceTypeVal(device.value.deviceType);
|
||
return deviceTypeVal && mgmtableDeviceTypes.includes(deviceTypeVal);
|
||
});
|
||
|
||
const onClickOpenMgmtPage = () => {
|
||
if (canOpenMgmtPage.value) {
|
||
const ipAddress = device.value.ipAddress;
|
||
if (ipAddress) {
|
||
const targetUrl = `http://${ipAddress}`;
|
||
window.open(targetUrl, '_blank');
|
||
} else {
|
||
window.$message.warning('未找到设备IP地址');
|
||
}
|
||
}
|
||
};
|
||
|
||
const canProbe = computed(() => device.value.snmpEnabled);
|
||
|
||
const { mutate: probeDevice, isPending: probing } = useMutation({
|
||
mutationFn: async () => {
|
||
await probeDeviceApi(device.value, { stationCode: stationCode.value });
|
||
},
|
||
onError: (error) => {
|
||
console.error(error);
|
||
window.$message.error(error.message);
|
||
},
|
||
});
|
||
|
||
const { mutate: getDeviceDetail, isPending: loading } = useMutation({
|
||
mutationFn: async () => {
|
||
return await detailDeviceApi(device.value, { stationCode: stationCode.value });
|
||
},
|
||
onSuccess: (device) => {
|
||
if (device) {
|
||
useDeviceStore().patch(stationCode.value, device);
|
||
}
|
||
},
|
||
onError: (error) => {
|
||
console.error(error);
|
||
window.$message.error(error.message);
|
||
},
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<NCard size="small" hoverable>
|
||
<template #header>
|
||
<NFlex :align="'center'">
|
||
<NTag v-if="status === '10'" size="small" type="success">在线</NTag>
|
||
<NTag v-else-if="status === '20'" size="small" type="error">离线</NTag>
|
||
<NTag v-else size="small" type="warning">未知</NTag>
|
||
<div>{{ name }}</div>
|
||
<NButton v-if="canOpenMgmtPage" ghost size="tiny" type="default" :focusable="false" @click="onClickOpenMgmtPage">管理</NButton>
|
||
</NFlex>
|
||
</template>
|
||
<template #default>
|
||
<div style="font-size: small; color: #666">
|
||
<div>
|
||
<span>设备类型:</span>
|
||
<span>{{ type }}</span>
|
||
</div>
|
||
<div>
|
||
<span>IP地址:</span>
|
||
<span>{{ ipAddr }}</span>
|
||
</div>
|
||
<div v-if="gbCode">
|
||
<span>国标编码:</span>
|
||
<span>{{ gbCode }}</span>
|
||
</div>
|
||
<!-- <div>
|
||
<span>上游设备:</span>
|
||
<span>{{ device.linkDescription ?? '暂无' }}</span>
|
||
</div> -->
|
||
<div v-if="device.snmpEnabled">
|
||
<span>上次诊断时间:</span>
|
||
<span>{{ device.lastDiagTime ?? '暂无' }}</span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<template #header-extra>
|
||
<NTooltip v-if="canProbe" trigger="hover">
|
||
<template #trigger>
|
||
<NButton size="small" quaternary circle :loading="probing" @click="() => probeDevice()">
|
||
<template #icon>
|
||
<NIcon :component="ApiOutlined" />
|
||
</template>
|
||
</NButton>
|
||
</template>
|
||
<template #default>
|
||
<span>获取最新诊断</span>
|
||
</template>
|
||
</NTooltip>
|
||
<NTooltip trigger="hover">
|
||
<template #trigger>
|
||
<NButton size="small" quaternary circle :loading="loading" @click="() => getDeviceDetail()">
|
||
<template #icon>
|
||
<NIcon :component="ReloadOutlined" />
|
||
</template>
|
||
</NButton>
|
||
</template>
|
||
<template #default>
|
||
<span>刷新设备</span>
|
||
</template>
|
||
</NTooltip>
|
||
</template>
|
||
</NCard>
|
||
</template>
|
||
|
||
<style scoped lang="scss"></style>
|