添加报警统计
This commit is contained in:
parent
7d18f8dca7
commit
65b70debed
@ -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;
|
||||||
|
}
|
||||||
|
340
src/components/alarm/alarmStatistics.vue
Normal file
340
src/components/alarm/alarmStatistics.vue
Normal 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>
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user