This commit is contained in:
fan 2023-12-21 10:29:39 +08:00
commit 2349f81149
9 changed files with 230 additions and 31 deletions

View File

@ -130,3 +130,11 @@ export async function recordAlarmReport(
const response = await api.post(`/api/alertRecord/report/${lineId}`, data); const response = await api.post(`/api/alertRecord/report/${lineId}`, data);
return response.data; return response.data;
} }
/**
*
* @param linId 线id
*/
export function resetApi(linId: number): Promise<string> {
return api.get(`${alertUriBase}/reset/${linId}`);
}

View File

@ -0,0 +1,80 @@
<template>
<draggable-dialog
ref="dialogRef"
@show="onDialogShow"
seamless
title="与卡斯柯连接状态信息"
:width="300"
:height="0"
>
<template v-slot:footer>
<q-table
ref="tableRef"
row-key="id"
v-model:pagination="pagination"
:rows="rows"
:columns="columns"
@request="onRequest"
:rows-per-page-options="[10, 20, 50, 100]"
>
</q-table>
</template>
</draggable-dialog>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue';
import DraggableDialog from './common/DraggableDialog.vue';
import { QTable } from 'quasar';
import { useLineNetStore } from 'src/stores/line-net-store';
import { state } from 'src/protos/system_warn_message';
const lineNetStore = useLineNetStore();
const dialogRef = ref<InstanceType<typeof DraggableDialog>>();
const tableRef = ref<QTable>();
const columns: QTable['columns'] = [
{ name: 'lineId', label: '线路ID', field: 'lineId', align: 'center' },
{
name: 'areaName',
label: '实时连接',
field: (row) => (row.occRealConned ? '是' : '否'),
align: 'center',
},
{
name: 'deviceType',
label: '非实时连接',
field: (row) => (row.occUnrealConned ? '是' : '否'),
align: 'center',
},
];
const rows = ref<state.WarnMessage[]>([]);
const pagination = ref({
sortBy: 'desc',
descending: false,
page: 1,
rowsPerPage: 10,
rowsNumber: 10,
});
watch(
() => lineNetStore.connectInfo,
() => {
onDialogShow();
}
);
const onRequest: QTable['onRequest'] = async (props) => {
const { page, rowsPerPage } = props.pagination;
pagination.value.page = page;
pagination.value.rowsPerPage = rowsPerPage;
const datas = lineNetStore.connectInfo?.msgs;
if (datas) {
rows.value = datas;
pagination.value.rowsNumber = datas.length;
}
};
const onDialogShow = () => {
tableRef.value?.requestServerInteraction();
};
</script>

View File

@ -0,0 +1,31 @@
import { HandleMessage, StompMessagingClient } from 'jl-graphic';
import { getJwtToken } from 'src/configs/TokenManage';
import { getWebsocketUrl } from 'src/configs/UrlManage';
export function webSocketConnect(destination: string, handler: HandleMessage) {
const socket = new StompMessagingClient({
wsUrl: `${getWebsocketUrl()}`,
token: getJwtToken() as string,
protocol: 'protobuf',
connectTimeout: 30 * 1000,
heartbeat: 60,
retryPeriod: 2 * 1000,
retryTimes: 100,
});
socket.on('connected', () => {
socket?.subscribe(destination, handler);
});
socket.on('disconnected', () => {
console.log('disconnected');
});
return socket;
}
export function closeWebSocketConnect(
socket: StompMessagingClient | null,
destination: string
) {
socket?.unsubscribe0(destination);
socket?.close();
socket = null;
}

View File

@ -1 +1,4 @@
// app global css in SCSS form // app global css in SCSS form
.my-notif-class {
margin-top: 50px;
}

View File

@ -130,7 +130,7 @@ export function initLineApp(): IGraphicApp {
sectionOperationPlugin.init(lineApp); sectionOperationPlugin.init(lineApp);
lineApp.enableWsMassaging({ lineApp.enableWsMassaging({
engine: ClientEngine.MQTT, engine: ClientEngine.Stomp,
wsUrl: getWebsocketUrl(), wsUrl: getWebsocketUrl(),
token: getJwtToken() as string, token: getJwtToken() as string,
}); });
@ -143,7 +143,8 @@ export function initLineApp(): IGraphicApp {
type: 'negative', type: 'negative',
timeout: 0, timeout: 0,
position: 'top-right', position: 'top-right',
message: '通信链接已断开!', message: '与WebSocket服务连接断开',
classes: 'my-notif-class',
}); });
} else if (msgNotify && connected) { } else if (msgNotify && connected) {
msgNotify(); msgNotify();

View File

@ -91,7 +91,8 @@ export function initLineNetApp(): IGraphicApp {
type: 'negative', type: 'negative',
timeout: 0, timeout: 0,
position: 'top-right', position: 'top-right',
message: '通信链接已断开!', message: '与WebSocket服务连接断开',
classes: 'my-notif-class',
}); });
} else if (msgNotify && connected) { } else if (msgNotify && connected) {
msgNotify(); msgNotify();

View File

@ -30,6 +30,13 @@
class="q-mr-sm" class="q-mr-sm"
@click="openSetAlarmTextDialog" @click="openSetAlarmTextDialog"
/> />
<q-btn
v-if="showSetAlarmTextButton && route.path.includes('line/monitor')"
color="warning"
label="初始化"
class="q-mr-sm"
@click="resetFn"
/>
<div class="q-gutter-sm row items-center no-wrap"> <div class="q-gutter-sm row items-center no-wrap">
<q-btn <q-btn
@ -48,6 +55,14 @@
v-if="$q.screen.gt.sm" v-if="$q.screen.gt.sm"
> >
</q-btn> </q-btn>
<q-btn
flat
dense
round
icon="connected_tv"
:color="lineNetStore.connectButtonColor"
@click="openConnectInfoDialog"
/>
<q-btn-dropdown <q-btn-dropdown
flat flat
stretch stretch
@ -87,10 +102,10 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'; import { ref, reactive, onMounted, onUnmounted } from 'vue';
import SysMenu from 'src/components/SysMenu.vue'; import SysMenu from 'src/components/SysMenu.vue';
import { useRouter, useRoute } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
import { Dialog, useQuasar } from 'quasar'; import { Dialog, DialogChainObject, useQuasar } from 'quasar';
import { clearJwtToken } from 'src/configs/TokenManage'; import { clearJwtToken } from 'src/configs/TokenManage';
import commonAlarm from 'src/components/alarm/commonAlarm.vue'; import commonAlarm from 'src/components/alarm/commonAlarm.vue';
import setAlarmText from 'src/components/alarm/setAlarmText.vue'; import setAlarmText from 'src/components/alarm/setAlarmText.vue';
@ -98,10 +113,23 @@ import setAlarmMock from 'src/components/alarm/setAlarmMock.vue';
import NCC from '/logo/NCC_bai.png'; import NCC from '/logo/NCC_bai.png';
import { getShowSetAlarmTextButton } from 'src/configs/UrlManage'; import { getShowSetAlarmTextButton } from 'src/configs/UrlManage';
import { useLineNetStore } from 'src/stores/line-net-store'; import { useLineNetStore } from 'src/stores/line-net-store';
import { resetApi } from 'src/api/AlertMock';
import { useLineStore } from 'src/stores/line-store';
import { errorNotify } from 'src/utils/CommonNotify';
import { Train } from 'src/graphics/train/Train';
import ConnectInfoDialog from 'src/components/ConnectInfoDialog.vue';
import { StompMessagingClient } from 'jl-graphic';
import { state } from 'src/protos/system_warn_message';
import {
webSocketConnect,
closeWebSocketConnect,
} from 'src/components/webSocketConnect';
const leftDrawerOpen = ref(false); const leftDrawerOpen = ref(false);
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const lineStore = useLineStore();
const lineNetStore = useLineNetStore();
function toggleLeftDrawer() { function toggleLeftDrawer() {
leftDrawerOpen.value = !leftDrawerOpen.value; leftDrawerOpen.value = !leftDrawerOpen.value;
onResize(); onResize();
@ -126,7 +154,7 @@ function onLeftResize(size: { width: number; height: number }) {
} }
const watchInteract = () => { const watchInteract = () => {
useLineNetStore().playAble = true; lineNetStore.playAble = true;
document.removeEventListener('click', watchInteract); document.removeEventListener('click', watchInteract);
document.removeEventListener('keydown', watchInteract); document.removeEventListener('keydown', watchInteract);
}; };
@ -137,6 +165,7 @@ onMounted(() => {
} }
document.addEventListener('click', watchInteract); document.addEventListener('click', watchInteract);
document.addEventListener('keydown', watchInteract); document.addEventListener('keydown', watchInteract);
socket = webSocketConnect(destination, handler);
}); });
// //
@ -154,6 +183,27 @@ function openSetAlarmTextDialog() {
}); });
} }
let connectInfoDialogInstance: DialogChainObject | null = null;
function openConnectInfoDialog() {
if (connectInfoDialogInstance) return;
connectInfoDialogInstance = $q
.dialog({ component: ConnectInfoDialog })
.onCancel(() => {
connectInfoDialogInstance = null;
});
}
let socket: StompMessagingClient | null = null;
const destination = '/queue/line/sysi';
function handler(message: Uint8Array) {
const storage = state.WarnLineMessage.deserialize(message);
lineNetStore.setConnectInfo(storage);
}
onUnmounted(() => {
closeWebSocketConnect(socket, destination);
});
function logOut() { function logOut() {
Dialog.create({ Dialog.create({
title: '登出确认', title: '登出确认',
@ -169,4 +219,26 @@ function logOut() {
function backConfirm() { function backConfirm() {
router.replace('/monitor'); router.replace('/monitor');
} }
function resetFn() {
Dialog.create({
title: '初始化确认',
message: '确认是否初始化?',
cancel: true,
persistent: true,
}).onOk(() => {
lineStore.lineId &&
resetApi(lineStore.lineId)
.then(() => {
const app = lineStore.getLineApp();
const trainList = app.queryStore.queryByType<Train>(Train.Type);
trainList.forEach((g) => {
app.deleteGraphics(g);
});
})
.catch((err) => {
errorNotify('初始化失败!', err);
});
});
}
</script> </script>

View File

@ -226,8 +226,6 @@ import {
ShowAlertStateData, ShowAlertStateData,
alertStatusOptions, alertStatusOptions,
} from 'src/components/alarm/alarmInfoEnum'; } from 'src/components/alarm/alarmInfoEnum';
import { getWebsocketUrl } from 'src/configs/UrlManage';
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 'jl-graphic'; import { StompMessagingClient } from 'jl-graphic';
@ -235,6 +233,10 @@ import alarmStatistics from 'src/components/alarm/alarmStatistics.vue';
import { errorNotify } from 'src/utils/CommonNotify'; import { errorNotify } from 'src/utils/CommonNotify';
import { pageQuery } from 'src/api/LineInfoApi'; import { pageQuery } from 'src/api/LineInfoApi';
import { ApiError } from 'src/boot/axios'; import { ApiError } from 'src/boot/axios';
import {
webSocketConnect,
closeWebSocketConnect,
} from 'src/components/webSocketConnect';
const $q = useQuasar(); const $q = useQuasar();
const lineNetStore = useLineNetStore(); const lineNetStore = useLineNetStore();
@ -370,7 +372,7 @@ onMounted(() => {
setTimeout(() => { setTimeout(() => {
tableRef.value.requestServerInteraction(); tableRef.value.requestServerInteraction();
lineNetStore.alarmInfoListTable = tableRef.value; lineNetStore.alarmInfoListTable = tableRef.value;
socketConnect(); socket = webSocketConnect(destination, handler);
}); });
}); });
@ -551,34 +553,13 @@ function openAlarmDialog(row: any) {
let socket: StompMessagingClient | null = null; let socket: StompMessagingClient | null = null;
const destination = '/queue/xian/ncc/alert'; const destination = '/queue/xian/ncc/alert';
function socketConnect() {
socket = new StompMessagingClient({
wsUrl: `${getWebsocketUrl()}`,
token: getJwtToken() as string,
protocol: 'protobuf',
connectTimeout: 30 * 1000,
heartbeat: 60,
retryPeriod: 2 * 1000,
retryTimes: 100,
});
socket.on('connected', () => {
socket?.subscribe(destination, handler);
});
}
function handler(message: Uint8Array) { function handler(message: Uint8Array) {
const storage = alert.NccAlertInfoMessage.deserialize(message); const storage = alert.NccAlertInfoMessage.deserialize(message);
lineNetStore.setAlarmInfo(storage.messages as []); lineNetStore.setAlarmInfo(storage.messages as []);
} }
function closeSocket() {
socket?.unsubscribe0(destination);
socket?.close();
socket = null;
}
onUnmounted(() => { onUnmounted(() => {
closeSocket(); closeWebSocketConnect(socket, destination);
}); });
// //

View File

@ -7,6 +7,7 @@ import {
} from 'src/drawApp/lineNetApp'; } from 'src/drawApp/lineNetApp';
import { markRaw } from 'vue'; import { markRaw } from 'vue';
import { QTable } from 'quasar'; import { QTable } from 'quasar';
import { state } from 'src/protos/system_warn_message';
export interface AlarmInfo { export interface AlarmInfo {
id: string; id: string;
level: string; level: string;
@ -28,6 +29,8 @@ export const useLineNetStore = defineStore('lineNet', {
alarmInfoListTable: undefined as QTable | undefined, alarmInfoListTable: undefined as QTable | undefined,
playAble: false, //是否允许播放音乐 playAble: false, //是否允许播放音乐
closeAllAlarmInfoDialog: false, closeAllAlarmInfoDialog: false,
connectButtonColor: 'green',
connectInfo: null as state.WarnLineMessage | null,
}), }),
getters: { getters: {
untreatedNum: (state) => { untreatedNum: (state) => {
@ -81,6 +84,25 @@ export const useLineNetStore = defineStore('lineNet', {
this.untreatedMap.set(item.id, item); this.untreatedMap.set(item.id, item);
}); });
}, },
setConnectInfo(data: state.WarnLineMessage) {
this.connectInfo = data;
const allConnectAmount = data.msgs.reduce((pre, cur) => {
let addValue = 0;
if (cur.occRealConned && cur.occUnrealConned) {
addValue = 2;
} else if (cur.occRealConned || cur.occUnrealConned) {
addValue = 1;
}
return pre + addValue;
}, 0);
if (allConnectAmount == data.msgs.length * 2) {
this.connectButtonColor = 'green';
} else if (allConnectAmount == 0) {
this.connectButtonColor = 'red';
} else {
this.connectButtonColor = 'yellow';
}
},
treatedAlarm(data: AlarmInfo) { treatedAlarm(data: AlarmInfo) {
if (this.untreatedMap.has(data.id)) { if (this.untreatedMap.has(data.id)) {
this.untreatedMap.delete(data.id); this.untreatedMap.delete(data.id);