应答器调整

This commit is contained in:
fan 2024-01-11 13:23:26 +08:00
parent 178c5758f2
commit 6dad42231d
3 changed files with 237 additions and 91 deletions

View File

@ -25,6 +25,9 @@
<spks-switch-state
v-else-if="lineStore.selectedGraphicType === SpksSwitch.Type"
/>
<transponder-state
v-else-if="lineStore.selectedGraphicType === Transponder.Type"
></transponder-state>
</div>
</q-scroll-area>
</template>
@ -51,6 +54,8 @@ import ScreenDoorState from './states/ScreenDoorState.vue';
import { ScreenDoor } from 'src/graphics/screenDoor/ScreenDoor';
import SpksSwitchState from './states/SpksSwitchState.vue';
import { SpksSwitch } from 'src/graphics/spksSwitch/SpksSwitch';
import TransponderState from './states/TransponderState.vue';
import { Transponder } from 'src/graphics/transponder/Transponder';
const lineStore = useLineStore();
</script>

View File

@ -0,0 +1,209 @@
<template>
<q-card flat bordered>
<q-card-section class="flex justify-between">
<div class="text-h6">应答器状态</div>
<q-btn-dropdown color="primary" label="操作">
<q-list>
<q-item
v-for="(item, index) in options"
:key="index"
clickable
v-close-popup
@click="doTransponderOperation(item.value)"
>
<q-item-section>
<q-item-label>{{ item.label }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</q-card-section>
<q-separator inset />
<q-card-section>
<q-input
outlined
readonly
v-model="transponderState.code"
label="id"
hint=""
/>
<q-input outlined readonly v-model.number="code" label="名称" />
<q-input
outlined
style="margin-top: 10px"
v-model="transponderState.km.coordinateSystem"
readonly
label="坐标系"
></q-input>
<q-input
outlined
style="margin-top: 10px"
v-model.number="kilometer"
readonly
type="number"
label="公里标(mm):"
/>
<q-select
outlined
v-model="transponderState.km.direction"
style="margin-top: 10px"
:options="directionOptions"
readonly
:map-options="true"
:emit-value="true"
label="方向"
></q-select>
<q-input
outlined
style="margin-top: 10px"
v-model="telegram"
readonly
label="报文"
/>
</q-card-section>
</q-card>
</template>
<script setup lang="ts">
import { useLineStore } from 'src/stores/line-store';
import { ref, watch, onMounted } from 'vue';
import { errorNotify } from 'src/utils/CommonNotify';
import { TransponderState } from 'src/drawApp/graphics/TransponderInteraction';
import { Transponder } from 'src/graphics/transponder/Transponder';
import MoveTransponder from 'src/components/draw-app/dialogs/MoveTransponder.vue';
import { Dialog } from 'quasar';
import {
updateMessageTransponder,
resetMessageTransponder,
updatePositionTransponder,
resetPositionTransponder,
} from 'src/api/Simulation';
const lineStore = useLineStore();
const transponderState = ref<TransponderState>(new TransponderState());
const code = ref('');
const telegram = ref('');
const kilometer = ref(0);
enum TransponderOperation {
MovePosition = 1,
ResetPosition = 2,
ModifyMessage = 3,
ResetMessage = 4,
}
const options = [
{
label: '移动应答器位置',
value: TransponderOperation.MovePosition,
},
{
label: '复位应答器',
value: TransponderOperation.ResetPosition,
},
{
label: '修改报文',
value: TransponderOperation.ModifyMessage,
},
{
label: '重置报文',
value: TransponderOperation.ResetMessage,
},
];
const directionOptions = [
{ label: '左行', value: 0 },
{ label: '右行', value: 1 },
];
watch(
() => lineStore.selectedGraphics,
(val) => {
if (val?.length == 1 && val[0].type == Transponder.Type) {
initTransponderState(val[0] as Transponder);
} else {
transponderState.value = new TransponderState();
}
}
);
function initTransponderState(transponder: Transponder) {
code.value = transponder.datas.code;
telegram.value = transponder.states.telegram?.join(',') || '';
kilometer.value = transponder.states.km?.kilometer || 0;
transponderState.value = transponder.states.clone() as TransponderState;
}
function doTransponderOperation(operation: number) {
const simulationId = useLineStore().simulationId || '';
const mapId = useLineStore().mapId as number;
if (operation === TransponderOperation.MovePosition) {
Dialog.create({
title: '移动应答器位置',
message: '',
component: MoveTransponder,
componentProps: {
code: code.value,
coordinateSystem: transponderState.value.km?.coordinateSystem,
kilometer: transponderState.value.km?.kilometer,
direction: transponderState.value.km?.direction,
},
cancel: true,
persistent: true,
}).onOk((data) => {
updatePositionTransponder({
simulationId,
mapId,
baliseId: transponderState.value.id,
km: {
coordinateSystem: transponderState.value.km?.coordinateSystem,
kilometer: data,
direction: transponderState.value.km?.direction,
},
}).catch((e) => errorNotify('移动应答器失败!', e));
});
} else if (operation === TransponderOperation.ResetPosition) {
resetPositionTransponder({
simulationId,
mapId,
baliseId: transponderState.value.id,
}).catch((e) => {
errorNotify('复位应答器失败!', e);
});
} else if (operation === TransponderOperation.ModifyMessage) {
updateMessageTransponder({
simulationId,
mapId,
baliseId: transponderState.value.id,
telegram: [0],
});
} else if (operation === TransponderOperation.ResetMessage) {
resetMessageTransponder({
simulationId,
mapId,
baliseId: transponderState.value.id,
}).catch((e) => errorNotify('重置应答器报文失败!', e));
}
}
onMounted(() => {
if (lineStore.selectedGraphics) {
initTransponderState(lineStore.selectedGraphics[0] as Transponder);
}
});
watch(
() => lineStore.socketStates,
(val) => {
if (val && transponderState.value.code) {
const find = val.find((item) => {
return (
item.graphicType == Transponder.Type &&
(item as TransponderState).code == transponderState.value.code
);
});
if (find) {
transponderState.value = find.clone() as TransponderState;
telegram.value = transponderState.value.telegram?.join(',') || '';
kilometer.value = transponderState.value.km.kilometer;
}
}
}
);
</script>

View File

@ -14,7 +14,6 @@ import {
IGraphicScene,
JlGraphic,
MenuItemOptions,
VectorText,
} from 'jl-graphic';
import { FederatedMouseEvent, DisplayObject, Graphics } from 'pixi.js';
import { useLineStore } from 'src/stores/line-store';
@ -26,7 +25,7 @@ import {
updatePositionTransponder,
resetPositionTransponder,
} from 'src/api/Simulation';
import { errorNotify, successNotify } from 'src/utils/CommonNotify';
import { errorNotify } from 'src/utils/CommonNotify';
import { state } from 'src/protos/device_state';
export class TransponderData
@ -133,7 +132,13 @@ export class TransponderState
this.states.id = id;
}
get km(): graphicData.KilometerSystem {
return this.states.km;
return this.states.km
? this.states.km
: new graphicData.KilometerSystem({
coordinateSystem: '',
kilometer: 0,
direction: 0,
});
}
set km(v: graphicData.KilometerSystem) {
this.states.km = new graphicData.KilometerSystem(v);
@ -160,7 +165,6 @@ export class TransponderState
export class TransponderOperationPlugin extends GraphicInteractionPlugin<Transponder> {
static Name = 'transponder_operate_menu';
private stayTimer: NodeJS.Timeout | null = null;
constructor(app: IGraphicScene) {
super(TransponderOperationPlugin.Name, app);
app.registerMenu(TransponderOperationMenu);
@ -177,86 +181,19 @@ export class TransponderOperationPlugin extends GraphicInteractionPlugin<Transpo
g.polygonGraphic.eventMode = 'static';
g.polygonGraphic.cursor = 'pointer';
g.polygonGraphic.scalable = true;
g.labelGraphic.selectable = true;
g.labelGraphic.eventMode = 'static';
g.on('mouseenter', this.onMouseEnter);
g.on('mouseleave', this.onMouseLeave);
g.selectable = true;
g.on('_rightclick', this.onContextMenu);
}
unbind(g: Transponder): void {
g.polygonGraphic.eventMode = 'none';
g.polygonGraphic.scalable = false;
g.polygonGraphic.rotatable = false;
g.labelGraphic.selectable = false;
g.labelGraphic.eventMode = 'none';
g.off('mouseenter', this.onMouseEnter);
g.off('mouseleave', this.onMouseLeave);
g.selectable = false;
g.off('_rightclick', this.onContextMenu);
}
onMouseEnter(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const transponder = target.getGraphic<Transponder>();
this.stayTimer = setTimeout(() => {
let type = '固定应答器';
if (transponder?.datas.type === TransponderTypeEnum.DB) {
type = '休眠唤醒应答器';
} else if (transponder?.datas.type === TransponderTypeEnum.WB) {
type = '休眠唤醒应答器';
} else if (transponder?.datas.type === TransponderTypeEnum.VB) {
type = '主信号应答器';
} else if (transponder?.datas.type === TransponderTypeEnum.IB) {
type = '预告应答器';
}
let kilometer = '';
if (
transponder?.states.km &&
transponder?.states.km.direction ===
graphicData.KilometerSystem.Direction.LEFT
) {
kilometer =
'ZSSK' +
Math.floor(transponder.states.km.kilometer / 1000000) +
'+' +
((transponder.states.km.kilometer % 1000000) / 1000).toFixed(2);
} else if (
transponder?.states.km &&
transponder?.states.km.direction ===
graphicData.KilometerSystem.Direction.RIGHT
) {
kilometer =
'YSSK' +
Math.floor(transponder.states.km.kilometer / 1000000) +
'+' +
((transponder.states.km.kilometer % 1000000) / 1000).toFixed(2);
}
const tipRect = new Graphics();
const tip = new VectorText(
` 应答器编号:${transponder?.datas.code}\n 应答器类型:${type}\n 应答器位置:${kilometer}\n 应答器报文:;\n 工作状态:应答器正常;`
);
tip.setVectorFontSize(16);
tipRect.beginFill('#FFFF00', 1);
tipRect.drawRect(0, 0, tip.getBounds().width, tip.getBounds().height + 2);
tip.style.fill = '#000000';
tipRect.endFill();
transponder?.addChild(tipRect);
transponder?.addChild(tip);
if (transponder) {
transponder.zIndex = 99;
}
}, 1000);
}
onMouseLeave(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const transponder = target.getGraphic<Transponder>();
if (this.stayTimer) {
clearTimeout(this.stayTimer);
}
if (transponder && transponder.children.length > 2) {
transponder?.removeChildAt(3);
transponder?.removeChildAt(2);
transponder.zIndex = 0;
}
}
onContextMenu(e: FederatedMouseEvent) {
const target = e.target as DisplayObject;
const transponder = target.getGraphic<Transponder>();
@ -271,9 +208,9 @@ export class TransponderOperationPlugin extends GraphicInteractionPlugin<Transpo
component: MoveTranspondere,
componentProps: {
code: transponder.datas.code,
coordinateSystem: transponder.datas.kilometerSystem.coordinateSystem,
kilometer: transponder.datas.kilometerSystem.kilometer,
direction: transponder.datas.kilometerSystem.direction,
coordinateSystem: transponder.states.km?.coordinateSystem,
kilometer: transponder.states.km?.kilometer,
direction: transponder.states.km?.direction,
},
cancel: true,
persistent: true,
@ -284,13 +221,14 @@ export class TransponderOperationPlugin extends GraphicInteractionPlugin<Transpo
baliseId: transponder.datas.id,
km: {
coordinateSystem:
transponder.states.km?.coordinateSystem ||
transponder.datas.kilometerSystem.coordinateSystem,
kilometer: data,
direction: transponder.datas.kilometerSystem.direction,
direction:
transponder.states.km?.direction ||
transponder.datas.kilometerSystem.direction,
},
})
.then(() => successNotify('移动应答器成功!'))
.catch((e) => errorNotify('移动应答器失败!', e));
}).catch((e) => errorNotify('移动应答器失败!', e));
});
};
recoverPosition.handler = () => {
@ -298,13 +236,9 @@ export class TransponderOperationPlugin extends GraphicInteractionPlugin<Transpo
simulationId,
mapId,
baliseId: transponder.datas.id,
})
.then(() => {
successNotify('复位应答器成功!');
})
.catch((e) => {
errorNotify('复位应答器失败!', e);
});
}).catch((e) => {
errorNotify('复位应答器失败!', e);
});
};
modifyMessage.handler = () => {
updateMessageTransponder({
@ -319,9 +253,7 @@ export class TransponderOperationPlugin extends GraphicInteractionPlugin<Transpo
simulationId,
mapId,
baliseId: transponder.datas.id,
})
.then(() => successNotify('重置应答器报文成功!'))
.catch((e) => errorNotify('重置应答器报文失败!', e));
}).catch((e) => errorNotify('重置应答器报文失败!', e));
};
}
}