Files
ndm-web-client/src/pages/alarm-page.vue

237 lines
7.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { ref, reactive, onBeforeMount, h } from 'vue';
import dayjs from 'dayjs';
import { useMutation } from '@tanstack/vue-query';
import type { DataTableColumns, DataTableRowData, PaginationProps, SelectOption } from 'naive-ui';
import { NForm, NInput, NButton, NSpace, NDataTable, NFormItemGi, NGrid, NSelect, NGridItem, NDatePicker } from 'naive-ui';
import { DeviceType, DeviceTypeName, type DeviceTypeCode } from '@/enums/device-type';
import { defaultExportByTemplate, postNdmDeviceAlarmLogPage } from '@/apis/requests/log/ndm-device-alarm-log';
import type { NdmDeviceAlarmLogResultVO } from '@/apis/models/device';
import { useStationStore } from '@/stores/station';
import { storeToRefs } from 'pinia';
import { downloadByData } from '@/utils/download';
import { JAVA_INTEGER_MAX_VALUE } from '@/constants';
const stationStore = useStationStore();
const { stationList } = storeToRefs(stationStore);
const searchFields = reactive({
stationCode_in: [] as string[],
deviceType_in: [] as string[],
deviceName_like: '',
// deviceId_likeRight: '',
alarmDate: [dayjs().startOf('date').subtract(7, 'day').valueOf(), dayjs().endOf('date').valueOf()] as [number, number],
});
const resetSearchFields = () => {
searchFields.stationCode_in = [];
searchFields.deviceType_in = [];
searchFields.deviceName_like = '';
searchFields.alarmDate = [dayjs().startOf('date').subtract(7, 'day').valueOf(), dayjs().endOf('date').valueOf()];
};
const tableColumns: DataTableColumns<NdmDeviceAlarmLogResultVO> = [
{ title: '告警流水号', key: 'alarmNo' },
{
title: '告警时间',
key: 'alarmDate',
render: (rowData /* , rowIndex */) => {
return dayjs(Number(rowData.alarmDate ?? 0)).format('YYYY-MM-DD HH:mm:ss');
},
},
{
title: '设备类型',
key: 'deviceType',
render: (rowData) => {
return DeviceTypeName[(rowData.deviceType ?? DeviceType.Camera) as DeviceTypeCode];
},
},
{ title: '设备名称', key: 'deviceName' },
{ title: '告警类型', key: 'alarmType', align: 'center' },
{ title: '故障级别', key: 'faultLevel', align: 'center' },
{ title: '故障编码', key: 'faultCode', align: 'center' },
{ title: '故障位置', key: 'faultLocation' },
{ title: '故障描述', key: 'faultDescription' },
{ title: '修复建议', key: 'alarmRepairSuggestion' },
{
title: '是否恢复',
key: 'alarmCategory',
align: 'center',
render: (rowData) => {
return rowData.alarmCategory === '2' ? '是' : '否';
},
},
{ title: '恢复时间', key: 'updatedTime' },
{
title: '告警确认',
key: 'alarmConfirm',
align: 'center',
render: (rowData) => {
return rowData.alarmConfirm === '1' ? '已确认' : '未确认';
},
},
// { title: '设备ID', key: 'deviceId' },
];
const tableData = ref<DataTableRowData[]>([]);
const tablePagination = reactive<PaginationProps>({
showSizePicker: true,
page: 1,
pageSize: 10,
pageSizes: [5, 10, 20, 50, 80, 100],
pageCount: 1,
itemCount: 0,
prefix: ({ itemCount }) => {
return h('div', {}, { default: () => `${itemCount}` });
},
onUpdatePage: (page: number) => {
tablePagination.page = page;
getAlarmList();
},
onUpdatePageSize: (pageSize: number) => {
tablePagination.pageSize = pageSize;
tablePagination.page = 1;
getAlarmList();
},
});
const { mutate: getAlarmList, isPending } = useMutation({
mutationFn: async () => {
const res = await postNdmDeviceAlarmLogPage('', {
model: {},
extra: {
stationCode_in: [...searchFields.stationCode_in],
deviceName_like: searchFields.deviceName_like,
deviceType_in: searchFields.deviceType_in,
alarmDate_ge: searchFields.alarmDate[0],
alarmDate_le: searchFields.alarmDate[1],
},
size: tablePagination.pageSize!,
current: tablePagination.page!,
sort: 'id',
order: 'descending',
});
const { records, pages, size, total } = res;
tablePagination.pageSize = parseInt(size);
tablePagination.pageCount = parseInt(pages);
tablePagination.itemCount = parseInt(total);
return records;
},
onSuccess: (records) => {
tableData.value = records;
},
onError: (error) => {
window.$message.error(error.message);
},
});
const onClickReset = () => {
resetSearchFields();
tablePagination.page = 1;
tablePagination.pageSize = 10;
tablePagination.pageCount = 1;
tablePagination.itemCount = 0;
getAlarmList();
};
const onClickQuery = () => getAlarmList();
const { mutate: downloadTableData, isPending: isDownloading } = useMutation({
mutationFn: async () => {
const data = await defaultExportByTemplate('', {
model: {},
extra: {
alarmDate_ge: searchFields.alarmDate[0],
alarmDate_le: searchFields.alarmDate[1],
},
current: 1,
size: JAVA_INTEGER_MAX_VALUE,
order: 'descending',
sort: 'id',
});
return data;
},
onSuccess: (data) => {
downloadByData(data, `设备告警记录.xlsx`);
},
onError: (error) => {
window.$message.error(error.message);
},
});
const exportTableData = () => downloadTableData();
onBeforeMount(() => getAlarmList());
</script>
<template>
<!-- 容器上下布局表格自适应剩余高度 -->
<div style="height: 100%; display: flex; flex-direction: column">
<!-- 查询面板 -->
<div style="flex: 0 0 auto; padding: 8px">
<NForm>
<NGrid :cols="3" :x-gap="24">
<NFormItemGi :span="1" label="车站" label-placement="left">
<NSelect
v-model:value="searchFields.stationCode_in"
:options="[
...stationList.map<SelectOption>((station) => ({
label: station.name,
value: station.deviceIdPrefix,
})),
]"
multiple
clearable
/>
</NFormItemGi>
<NFormItemGi :span="1" label="设备类型" label-placement="left">
<NSelect
v-model:value="searchFields.deviceType_in"
:options="[
...Object.values(DeviceType).map<SelectOption>((deviceType) => {
return {
label: DeviceTypeName[deviceType],
value: deviceType,
};
}),
]"
placeholder="请选择设备类型"
multiple
clearable
/>
</NFormItemGi>
<NFormItemGi :span="1" label="设备名称" label-placement="left">
<NInput v-model:value="searchFields.deviceName_like" placeholder="请输入设备名称" clearable />
</NFormItemGi>
<NFormItemGi :span="1" label="告警发生时间" label-placement="left">
<NDatePicker v-model:value="searchFields.alarmDate" type="datetimerange" />
</NFormItemGi>
</NGrid>
<!-- 按钮 -->
<NGrid :cols="1">
<NGridItem>
<NSpace>
<NButton @click="onClickReset">重置</NButton>
<NButton type="primary" :loading="isPending" @click="onClickQuery">查询</NButton>
</NSpace>
</NGridItem>
</NGrid>
</NForm>
</div>
<!-- 工具栏横向右对齐按钮 -->
<div style="flex: 0 0 auto; display: flex; align-items: center; padding: 8px">
<div style="font-size: medium">设备告警列表</div>
<NSpace style="margin-left: auto">
<NButton type="primary" :loading="isDownloading" @click="exportTableData">导出</NButton>
</NSpace>
</div>
<!-- 表格区域填满剩余空间 -->
<div style="flex: 1 1 auto; min-height: 0; padding: 8px">
<NDataTable remote :columns="tableColumns" :data="tableData" :pagination="tablePagination" :loading="isPending" :single-line="false" flex-height style="height: 100%" />
</div>
</div>
</template>
<style scoped lang="scss"></style>