添加报警统计

This commit is contained in:
dong 2023-09-13 16:28:41 +08:00
parent 7d18f8dca7
commit 65b70debed
3 changed files with 378 additions and 1 deletions

View File

@ -81,3 +81,26 @@ export function recordConfirmAlarmInfoByTipType(
export function recordFailAlarmInfoById(id: number) { export function recordFailAlarmInfoById(id: number) {
return api.get(`/api/alertRecord/fail/${id}`); return api.get(`/api/alertRecord/fail/${id}`);
} }
export interface IReportParams {
alertTypes?: string[];
beginDateTime?: string;
endDateTime?: string;
}
interface IReportRes {
alertType: string;
counter: number;
}
/**
*
* @param lineId 线id
*/
export async function recordAlarmReport(
lineId: number,
data: IReportParams
): Promise<IReportRes[]> {
const response = await api.post(`/api/alertRecord/report/${lineId}`, data);
return response.data;
}

View File

@ -0,0 +1,340 @@
<template>
<draggable-dialog
seamless
title="报警统计"
:width="dialogWidth"
:height="dialogHeight"
>
<q-table
ref="tableRef"
:style="{ height: dialogHeight + 'px' }"
:rows="rows"
:columns="columnDefs"
row-key="index"
v-model:pagination="pagination"
:rows-per-page-options="[0]"
:loading="loading"
:filter="filter"
binary-state-sort
virtual-scroll
>
<template v-slot:top-right>
<q-form ref="myForm" @submit="onRequest">
<div class="q-gutter-md row justify-center items-start">
<q-input
dense
v-model.number="filter.lineId"
label="线路ID"
type="number"
style="width: 80px"
no-error-icon
lazy-rules
:rules="[(val) => val > 0 || '请输入正确线路ID']"
/>
<q-input
dense
v-model="filter.beginDateTime"
label="开始时间"
no-error-icon
mask="####-##-## ##:##:##"
hint="例如2023-09-05 16:05:09"
lazy-rules
:rules="[timeRangeValidation]"
:error="errorBeginTime"
:error-message="errorMessageBeginTime"
>
<template v-slot:prepend>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy
cover
transition-show="scale"
transition-hide="scale"
>
<q-date
v-model="filter.beginDateTime"
mask="YYYY-MM-DD HH:mm:ss"
landscape
>
<div class="row items-center justify-end">
<q-btn
v-close-popup
label="关闭"
color="primary"
flat
/>
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
<template v-slot:append>
<q-icon name="access_time" class="cursor-pointer">
<q-popup-proxy
cover
transition-show="scale"
transition-hide="scale"
>
<q-time
v-model="filter.beginDateTime"
mask="YYYY-MM-DD HH:mm:ss"
with-seconds
landscape
format24h
>
<div class="row items-center justify-end">
<q-btn
v-close-popup
label="关闭"
color="primary"
flat
/>
</div>
</q-time>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
<q-input
dense
v-model="filter.endDateTime"
label="结束时间"
no-error-icon
mask="####-##-## ##:##:##"
hint="例如2023-09-05 16:05:09"
lazy-rules
:rules="[timeRangeValidation]"
:error="errorEndTime"
:error-message="errorMessageEndTime"
>
<template v-slot:prepend>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy
cover
transition-show="scale"
transition-hide="scale"
>
<q-date
v-model="filter.endDateTime"
mask="YYYY-MM-DD HH:mm:ss"
landscape
>
<div class="row items-center justify-end">
<q-btn
v-close-popup
label="关闭"
color="primary"
flat
/>
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
<template v-slot:append>
<q-icon name="access_time" class="cursor-pointer">
<q-popup-proxy
cover
transition-show="scale"
transition-hide="scale"
>
<q-time
v-model="filter.endDateTime"
mask="YYYY-MM-DD HH:mm:ss"
with-seconds
landscape
format24h
>
<div class="row items-center justify-end">
<q-btn
v-close-popup
label="关闭"
color="primary"
flat
/>
</div>
</q-time>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
<q-select
dense
v-model="filter.alertTypes"
:options="typeOptions"
multiple
emit-value
map-options
options-dense
class="ellipsis"
label="类型"
style="width: 200px"
/>
<q-btn color="primary" label="查询" type="submit" />
</div>
</q-form>
</template>
<template v-slot:body-cell-index="props">
<q-td :props="props">
<span>{{ props.rowIndex + 1 }}</span>
</q-td>
</template>
</q-table>
</draggable-dialog>
</template>
<script setup lang="ts">
import DraggableDialog from '../common/DraggableDialog.vue';
import { ref, reactive, computed } from 'vue';
import { useQuasar, type QTableColumn, QForm, date } from 'quasar';
import { IReportParams, recordAlarmReport } from 'src/api/AlertMock';
import { showAlertTypeData, saveAlertTypeData } from './alarmInfoEnum';
const $q = useQuasar();
const dialogWidth = window.screen.width * 0.5;
const dialogHeight = window.screen.height * 0.5;
const columnDefs: QTableColumn[] = [
{
name: 'index',
label: '编号',
field: 'index',
align: 'center',
},
{
name: 'alertType',
label: '故障类型',
field: (row) => {
if (row.alertType) {
return (showAlertTypeData as never)[row.alertType];
}
},
align: 'center',
},
{
name: 'counter',
label: '数量',
field: 'counter',
align: 'center',
},
];
const typeOptions = computed(() => {
const list: { label: string; value: string }[] = [];
for (let i in saveAlertTypeData) {
const obj = {
label: i,
value: saveAlertTypeData[i as keyof typeof saveAlertTypeData],
};
list.push(obj);
}
return list;
});
interface Ifilter extends IReportParams {
lineId: number;
}
const rows = reactive([]);
const filter = reactive<Ifilter>({
alertTypes: [],
lineId: 3,
beginDateTime: '',
endDateTime: '',
});
const loading = ref(false);
const pagination = ref({
sortBy: 'desc',
descending: false,
page: 1,
rowsPerPage: 10,
rowsNumber: 0,
});
function onRequest() {
myForm.value?.validate().then(async (res) => {
if (res) {
loading.value = true;
try {
const params: IReportParams = {};
if (filter.alertTypes?.length) {
Object.assign(params, { alertTypes: filter.alertTypes });
}
if (filter.beginDateTime) {
Object.assign(params, { beginDateTime: filter.beginDateTime });
}
if (filter.endDateTime) {
Object.assign(params, { endDateTime: filter.endDateTime });
}
const response = await recordAlarmReport(filter.lineId, params);
pagination.value.rowsNumber = response.length;
pagination.value.rowsPerPage = response.length;
rows.splice(0, rows.length, ...(response as []));
} catch (err) {
$q.notify({
type: 'negative',
message: '无法获取报警统计列表',
});
} finally {
loading.value = false;
}
}
});
}
const myForm = ref<QForm | null>(null);
const errorBeginTime = ref(false);
const errorEndTime = ref(false);
const errorMessageBeginTime = ref('');
const errorMessageEndTime = ref('');
function timeRangeValidation() {
const Reg = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
if (filter.beginDateTime) {
if (
!date.isValid(filter.beginDateTime) ||
!Reg.test(filter.beginDateTime)
) {
errorBeginTime.value = true;
errorMessageBeginTime.value = '请输入正确的时间!';
return false;
} else {
filter.beginDateTime = date.formatDate(
filter.beginDateTime,
'YYYY-MM-DD HH:mm:ss'
);
}
}
if (filter.endDateTime) {
if (!date.isValid(filter.endDateTime) || !Reg.test(filter.endDateTime)) {
errorEndTime.value = true;
errorMessageEndTime.value = '请输入正确的时间!';
return false;
} else {
filter.endDateTime = date.formatDate(
filter.endDateTime,
'YYYY-MM-DD HH:mm:ss'
);
}
}
if (
filter.beginDateTime &&
filter.endDateTime &&
new Date(filter.endDateTime).getTime() <
new Date(filter.beginDateTime).getTime()
) {
errorBeginTime.value = true;
errorEndTime.value = true;
errorMessageBeginTime.value = '开始时间不能大于结束时间!';
errorMessageEndTime.value = '结束时间不能小于开始时间!';
return false;
}
errorBeginTime.value = false;
errorEndTime.value = false;
errorMessageBeginTime.value = '';
errorMessageEndTime.value = '';
return true;
}
</script>

View File

@ -15,7 +15,9 @@
@request="onRequest" @request="onRequest"
> >
<template v-slot:top-right> <template v-slot:top-right>
<q-btn color="primary" label="查询" icon="search" /> <div class="q-gutter-sm row justify-center">
<q-btn color="primary" label="报警统计" @click="showStatistics" />
</div>
</template> </template>
<template v-slot:body-cell-operations="props"> <template v-slot:body-cell-operations="props">
<q-td :props="props"> <q-td :props="props">
@ -46,6 +48,7 @@ import { getJwtToken } from 'src/configs/TokenManage';
import { alert } from 'src/protos/alertInfo'; import { alert } from 'src/protos/alertInfo';
import { useLineNetStore } from 'src/stores/line-net-store'; import { useLineNetStore } from 'src/stores/line-net-store';
import { StompMessagingClient } from 'src/jl-graphic/message/WsMsgBroker'; import { StompMessagingClient } from 'src/jl-graphic/message/WsMsgBroker';
import alarmStatistics from 'src/components/alarm/alarmStatistics.vue';
const $q = useQuasar(); const $q = useQuasar();
const lineNetStore = useLineNetStore(); const lineNetStore = useLineNetStore();
@ -218,4 +221,15 @@ function closeSocket() {
onUnmounted(() => { onUnmounted(() => {
closeSocket(); closeSocket();
}); });
//
const alarmStatisticsDialog = ref();
function showStatistics() {
if (alarmStatisticsDialog.value) return;
alarmStatisticsDialog.value = $q
.dialog({ component: alarmStatistics })
.onCancel(() => {
alarmStatisticsDialog.value = null;
});
}
</script> </script>