与卡斯柯连接状态信息

This commit is contained in:
joylink_zhaoerwei 2023-12-20 16:23:17 +08:00
parent 232536ae34
commit 9edc6971ca
7 changed files with 402 additions and 59 deletions

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,34 @@
import { HandleMessage, StompMessagingClient } from 'jl-graphic';
import { getJwtToken } from 'src/configs/TokenManage';
import { getWebsocketUrl } from 'src/configs/UrlManage';
export function webSocketConnect(
socket: StompMessagingClient | null,
destination: string,
handler: HandleMessage
) {
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(6666);
});
}
export function closeWebSocketConnect(
socket: StompMessagingClient | null,
destination: string
) {
socket?.unsubscribe0(destination);
socket?.close();
socket = null;
}

View File

@ -55,6 +55,14 @@
v-if="$q.screen.gt.sm"
>
</q-btn>
<q-btn
flat
dense
round
icon="connected_tv"
:color="lineNetStore.connectButtonColor"
@click="openConnectInfoDialog"
/>
<q-btn-dropdown
flat
stretch
@ -94,10 +102,10 @@
</template>
<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 { useRouter, useRoute } from 'vue-router';
import { Dialog, useQuasar } from 'quasar';
import { Dialog, DialogChainObject, useQuasar } from 'quasar';
import { clearJwtToken } from 'src/configs/TokenManage';
import commonAlarm from 'src/components/alarm/commonAlarm.vue';
import setAlarmText from 'src/components/alarm/setAlarmText.vue';
@ -109,11 +117,19 @@ 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 router = useRouter();
const route = useRoute();
const lineStore = useLineStore();
const lineNetStore = useLineNetStore();
function toggleLeftDrawer() {
leftDrawerOpen.value = !leftDrawerOpen.value;
onResize();
@ -138,7 +154,7 @@ function onLeftResize(size: { width: number; height: number }) {
}
const watchInteract = () => {
useLineNetStore().playAble = true;
lineNetStore.playAble = true;
document.removeEventListener('click', watchInteract);
document.removeEventListener('keydown', watchInteract);
};
@ -149,6 +165,7 @@ onMounted(() => {
}
document.addEventListener('click', watchInteract);
document.addEventListener('keydown', watchInteract);
webSocketConnect(socket, destination, handler);
});
//
@ -166,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() {
Dialog.create({
title: '登出确认',

View File

@ -226,8 +226,6 @@ import {
ShowAlertStateData,
alertStatusOptions,
} from 'src/components/alarm/alarmInfoEnum';
import { getWebsocketUrl } from 'src/configs/UrlManage';
import { getJwtToken } from 'src/configs/TokenManage';
import { alert } from 'src/protos/alertInfo';
import { useLineNetStore } from 'src/stores/line-net-store';
import { StompMessagingClient } from 'jl-graphic';
@ -235,6 +233,10 @@ import alarmStatistics from 'src/components/alarm/alarmStatistics.vue';
import { errorNotify } from 'src/utils/CommonNotify';
import { pageQuery } from 'src/api/LineInfoApi';
import { ApiError } from 'src/boot/axios';
import {
webSocketConnect,
closeWebSocketConnect,
} from 'src/components/webSocketConnect';
const $q = useQuasar();
const lineNetStore = useLineNetStore();
@ -370,7 +372,7 @@ onMounted(() => {
setTimeout(() => {
tableRef.value.requestServerInteraction();
lineNetStore.alarmInfoListTable = tableRef.value;
socketConnect();
webSocketConnect(socket, destination, handler);
});
});
@ -551,34 +553,13 @@ function openAlarmDialog(row: any) {
let socket: StompMessagingClient | null = null;
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) {
const storage = alert.NccAlertInfoMessage.deserialize(message);
lineNetStore.setAlarmInfo(storage.messages as []);
}
function closeSocket() {
socket?.unsubscribe0(destination);
socket?.close();
socket = null;
}
onUnmounted(() => {
closeSocket();
closeWebSocketConnect(socket, destination);
});
//

View File

@ -9,10 +9,10 @@ export namespace state {
export class Section extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
id?: string;
id?: number;
code?: string;
childrenId?: string[];
physicalSectionId?: string;
childrenId?: number[];
physicalSectionId?: number;
destinationCode?: string;
kilometer?: DeviceKilometer;
}) {
@ -40,9 +40,9 @@ export namespace state {
}
}
get id() {
return pb_1.Message.getFieldWithDefault(this, 1, "") as string;
return pb_1.Message.getFieldWithDefault(this, 1, 0) as number;
}
set id(value: string) {
set id(value: number) {
pb_1.Message.setField(this, 1, value);
}
get code() {
@ -52,15 +52,15 @@ export namespace state {
pb_1.Message.setField(this, 2, value);
}
get childrenId() {
return pb_1.Message.getFieldWithDefault(this, 3, []) as string[];
return pb_1.Message.getFieldWithDefault(this, 3, []) as number[];
}
set childrenId(value: string[]) {
set childrenId(value: number[]) {
pb_1.Message.setField(this, 3, value);
}
get physicalSectionId() {
return pb_1.Message.getFieldWithDefault(this, 4, "") as string;
return pb_1.Message.getFieldWithDefault(this, 4, 0) as number;
}
set physicalSectionId(value: string) {
set physicalSectionId(value: number) {
pb_1.Message.setField(this, 4, value);
}
get destinationCode() {
@ -79,10 +79,10 @@ export namespace state {
return pb_1.Message.getField(this, 6) != null;
}
static fromObject(data: {
id?: string;
id?: number;
code?: string;
childrenId?: string[];
physicalSectionId?: string;
childrenId?: number[];
physicalSectionId?: number;
destinationCode?: string;
kilometer?: ReturnType<typeof DeviceKilometer.prototype.toObject>;
}): Section {
@ -109,10 +109,10 @@ export namespace state {
}
toObject() {
const data: {
id?: string;
id?: number;
code?: string;
childrenId?: string[];
physicalSectionId?: string;
childrenId?: number[];
physicalSectionId?: number;
destinationCode?: string;
kilometer?: ReturnType<typeof DeviceKilometer.prototype.toObject>;
} = {};
@ -140,14 +140,14 @@ export namespace state {
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.id.length)
writer.writeString(1, this.id);
if (this.id != 0)
writer.writeUint32(1, this.id);
if (this.code.length)
writer.writeString(2, this.code);
if (this.childrenId.length)
writer.writeRepeatedString(3, this.childrenId);
if (this.physicalSectionId.length)
writer.writeString(4, this.physicalSectionId);
writer.writePackedUint32(3, this.childrenId);
if (this.physicalSectionId != 0)
writer.writeUint32(4, this.physicalSectionId);
if (this.destinationCode.length)
writer.writeString(5, this.destinationCode);
if (this.has_kilometer)
@ -162,16 +162,16 @@ export namespace state {
break;
switch (reader.getFieldNumber()) {
case 1:
message.id = reader.readString();
message.id = reader.readUint32();
break;
case 2:
message.code = reader.readString();
break;
case 3:
pb_1.Message.addToRepeatedField(message, 3, reader.readString());
message.childrenId = reader.readPackedUint32();
break;
case 4:
message.physicalSectionId = reader.readString();
message.physicalSectionId = reader.readUint32();
break;
case 5:
message.destinationCode = reader.readString();
@ -194,7 +194,7 @@ export namespace state {
export class Turnout extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
id?: string;
id?: number;
code?: string;
kilometer?: DeviceKilometer;
}) {
@ -213,9 +213,9 @@ export namespace state {
}
}
get id() {
return pb_1.Message.getFieldWithDefault(this, 1, "") as string;
return pb_1.Message.getFieldWithDefault(this, 1, 0) as number;
}
set id(value: string) {
set id(value: number) {
pb_1.Message.setField(this, 1, value);
}
get code() {
@ -234,7 +234,7 @@ export namespace state {
return pb_1.Message.getField(this, 3) != null;
}
static fromObject(data: {
id?: string;
id?: number;
code?: string;
kilometer?: ReturnType<typeof DeviceKilometer.prototype.toObject>;
}): Turnout {
@ -252,7 +252,7 @@ export namespace state {
}
toObject() {
const data: {
id?: string;
id?: number;
code?: string;
kilometer?: ReturnType<typeof DeviceKilometer.prototype.toObject>;
} = {};
@ -271,8 +271,8 @@ export namespace state {
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.id.length)
writer.writeString(1, this.id);
if (this.id != 0)
writer.writeUint32(1, this.id);
if (this.code.length)
writer.writeString(2, this.code);
if (this.has_kilometer)
@ -287,7 +287,7 @@ export namespace state {
break;
switch (reader.getFieldNumber()) {
case 1:
message.id = reader.readString();
message.id = reader.readUint32();
break;
case 2:
message.code = reader.readString();

View File

@ -0,0 +1,188 @@
/**
* Generated by the protoc-gen-ts. DO NOT EDIT!
* compiler version: 4.23.1
* source: system_warn_message.proto
* git: https://github.com/thesayyn/protoc-gen-ts */
import * as pb_1 from "google-protobuf";
export namespace state {
export class WarnLineMessage extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
msgs?: WarnMessage[];
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [1], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("msgs" in data && data.msgs != undefined) {
this.msgs = data.msgs;
}
}
}
get msgs() {
return pb_1.Message.getRepeatedWrapperField(this, WarnMessage, 1) as WarnMessage[];
}
set msgs(value: WarnMessage[]) {
pb_1.Message.setRepeatedWrapperField(this, 1, value);
}
static fromObject(data: {
msgs?: ReturnType<typeof WarnMessage.prototype.toObject>[];
}): WarnLineMessage {
const message = new WarnLineMessage({});
if (data.msgs != null) {
message.msgs = data.msgs.map(item => WarnMessage.fromObject(item));
}
return message;
}
toObject() {
const data: {
msgs?: ReturnType<typeof WarnMessage.prototype.toObject>[];
} = {};
if (this.msgs != null) {
data.msgs = this.msgs.map((item: WarnMessage) => item.toObject());
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.msgs.length)
writer.writeRepeatedMessage(1, this.msgs, (item: WarnMessage) => item.serialize(writer));
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): WarnLineMessage {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new WarnLineMessage();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
reader.readMessage(message.msgs, () => pb_1.Message.addToRepeatedWrapperField(message, 1, WarnMessage.deserialize(reader), WarnMessage));
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): WarnLineMessage {
return WarnLineMessage.deserialize(bytes);
}
}
export class WarnMessage extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
lineId?: number;
occRealConned?: boolean;
occUnrealConned?: boolean;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("lineId" in data && data.lineId != undefined) {
this.lineId = data.lineId;
}
if ("occRealConned" in data && data.occRealConned != undefined) {
this.occRealConned = data.occRealConned;
}
if ("occUnrealConned" in data && data.occUnrealConned != undefined) {
this.occUnrealConned = data.occUnrealConned;
}
}
}
get lineId() {
return pb_1.Message.getFieldWithDefault(this, 1, 0) as number;
}
set lineId(value: number) {
pb_1.Message.setField(this, 1, value);
}
get occRealConned() {
return pb_1.Message.getFieldWithDefault(this, 2, false) as boolean;
}
set occRealConned(value: boolean) {
pb_1.Message.setField(this, 2, value);
}
get occUnrealConned() {
return pb_1.Message.getFieldWithDefault(this, 3, false) as boolean;
}
set occUnrealConned(value: boolean) {
pb_1.Message.setField(this, 3, value);
}
static fromObject(data: {
lineId?: number;
occRealConned?: boolean;
occUnrealConned?: boolean;
}): WarnMessage {
const message = new WarnMessage({});
if (data.lineId != null) {
message.lineId = data.lineId;
}
if (data.occRealConned != null) {
message.occRealConned = data.occRealConned;
}
if (data.occUnrealConned != null) {
message.occUnrealConned = data.occUnrealConned;
}
return message;
}
toObject() {
const data: {
lineId?: number;
occRealConned?: boolean;
occUnrealConned?: boolean;
} = {};
if (this.lineId != null) {
data.lineId = this.lineId;
}
if (this.occRealConned != null) {
data.occRealConned = this.occRealConned;
}
if (this.occUnrealConned != null) {
data.occUnrealConned = this.occUnrealConned;
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.lineId != 0)
writer.writeInt32(1, this.lineId);
if (this.occRealConned != false)
writer.writeBool(2, this.occRealConned);
if (this.occUnrealConned != false)
writer.writeBool(3, this.occUnrealConned);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): WarnMessage {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new WarnMessage();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
message.lineId = reader.readInt32();
break;
case 2:
message.occRealConned = reader.readBool();
break;
case 3:
message.occUnrealConned = reader.readBool();
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): WarnMessage {
return WarnMessage.deserialize(bytes);
}
}
}

View File

@ -7,6 +7,7 @@ import {
} from 'src/drawApp/lineNetApp';
import { markRaw } from 'vue';
import { QTable } from 'quasar';
import { state } from 'src/protos/system_warn_message';
export interface AlarmInfo {
id: string;
level: string;
@ -28,6 +29,8 @@ export const useLineNetStore = defineStore('lineNet', {
alarmInfoListTable: undefined as QTable | undefined,
playAble: false, //是否允许播放音乐
closeAllAlarmInfoDialog: false,
connectButtonColor: 'green',
connectInfo: null as state.WarnLineMessage | null,
}),
getters: {
untreatedNum: (state) => {
@ -81,6 +84,25 @@ export const useLineNetStore = defineStore('lineNet', {
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) {
if (this.untreatedMap.has(data.id)) {
this.untreatedMap.delete(data.id);