Merge branch 'master' of git.code.tencent.com:beijing-rtss-test/bj-rtss-client

This commit is contained in:
Yuan 2023-09-19 09:17:10 +08:00
commit 717e5388bc
34 changed files with 813 additions and 698 deletions

View File

@ -20,6 +20,7 @@ export interface MapInfo {
category: string;
id: number;
name: string;
type: number;
}
export interface LinkInfo {

View File

@ -65,8 +65,8 @@ import { useDialogPluginComponent } from 'quasar';
import { getProjectLinkTrainSizeByMapId } from 'src/api/ProjectLinkApi';
import { Section } from 'src/graphics/section/Section';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { useLineStore } from 'src/stores/line-store';
import { onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
const props = defineProps({
dev: {
@ -92,13 +92,13 @@ const { dialogRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();
const offsetRules = (val: number) =>
(val >= 0 && val <= props.kmLength) || `偏移量在0到${props.kmLength}之间!`;
const route = useRoute();
const lengthOptions = ref<string[]>([]);
const trainLength = ref('');
const lineStore = useLineStore();
onMounted(() => {
const mapId = route.query.mapId as string;
const mapId = lineStore.mapId;
if (mapId) {
getLengthOption(+mapId);
getLengthOption(mapId);
}
});

View File

@ -121,7 +121,7 @@ import { Section } from 'src/graphics/section/Section';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { GraphicIdGenerator } from 'src/jl-graphic';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, ref, watch } from 'vue';
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue';
const drawStore = useDrawStore();
const axleCountingModel = reactive(new AxleCountingData());
@ -190,27 +190,8 @@ const turnoutRelations = computed(() => {
return Array.from(new Set(ref));
});
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == AxleCounting.Type) {
axleCountingModel.copyFrom(val.saveData() as AxleCountingData);
invent.value = (showSelectData as never)[axleCountingModel.invent + ''];
if (axleCountingModel.kilometerSystem) {
kilometerSystem.coordinateSystem =
axleCountingModel.kilometerSystem.coordinateSystem;
kilometerSystem.kilometer = axleCountingModel.kilometerSystem.kilometer;
kilometerSystem.direction = axleCountingModel.kilometerSystem.direction;
} else {
kilometerSystem.coordinateSystem = '';
kilometerSystem.kilometer = 0;
kilometerSystem.direction = 0;
}
}
}
);
onMounted(() => {
drawStore.bindFormData(axleCountingModel);
const axleCounting = drawStore.selectedGraphic as AxleCounting;
if (axleCounting) {
axleCountingModel.copyFrom(axleCounting.saveData());
@ -223,6 +204,9 @@ onMounted(() => {
}
}
});
onUnmounted(() => {
drawStore.unbindFormData(axleCountingModel);
});
function oneClickAxleCounting() {
const select = drawStore.selectedGraphic as AxleCounting;

View File

@ -69,7 +69,7 @@ import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, watch } from 'vue';
import { computed, onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const axleCountingSectionModel = reactive(new AxleCountingSectionData());
@ -79,24 +79,16 @@ enum turoutPos {
'反位',
}
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == AxleCountingSection.Type) {
axleCountingSectionModel.copyFrom(
val.saveData() as AxleCountingSectionData
);
}
}
);
onMounted(() => {
drawStore.bindFormData(axleCountingSectionModel);
const axleCountingSection = drawStore.selectedGraphic as AxleCountingSection;
if (axleCountingSection) {
axleCountingSectionModel.copyFrom(axleCountingSection.saveData());
}
});
onUnmounted(() => {
drawStore.unbindFormData(axleCountingSectionModel);
});
function onUpdate() {
const axleCountingSection = drawStore.selectedGraphic as AxleCountingSection;

View File

@ -46,26 +46,14 @@ import { CurvatureData } from 'src/drawApp/graphics/CurvatureInteraction';
import { Curvature } from 'src/graphics/curvature/Curvature';
import { CurvatureKiloMarker } from 'src/graphics/curvatureKiloMarker/CurvatureKiloMarker';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, ref, watch } from 'vue';
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue';
const drawStore = useDrawStore();
const curvatureModel = reactive(new CurvatureData());
const direction = ref('无曲度');
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == Curvature.Type) {
curvatureModel.copyFrom(val.saveData() as CurvatureData);
if (curvatureModel.curvatureNumber !== 0) {
direction.value = curvatureModel.curvatureNumber > 0 ? '外侧' : '内侧';
}
}
}
);
onMounted(() => {
drawStore.bindFormData(curvatureModel);
const curvature = drawStore.selectedGraphic as Curvature;
if (curvature) {
curvatureModel.copyFrom(curvature.saveData());
@ -74,6 +62,9 @@ onMounted(() => {
}
}
});
onUnmounted(() => {
drawStore.unbindFormData(curvatureModel);
});
function onUpdate() {
const curvature = drawStore.selectedGraphic as Curvature;

View File

@ -30,26 +30,21 @@
import { EsbButtonData } from 'src/drawApp/graphics/EsbButtonInteraction';
import { EsbButton } from 'src/graphics/esbButton/EsbButton';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch } from 'vue';
import { onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const esbButtonModel = reactive(new EsbButtonData());
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == EsbButton.Type) {
esbButtonModel.copyFrom(val.saveData() as EsbButtonData);
}
}
);
onMounted(() => {
drawStore.bindFormData(esbButtonModel);
const esbButton = drawStore.selectedGraphic as EsbButton;
if (esbButton) {
esbButtonModel.copyFrom(esbButton.saveData());
}
});
onUnmounted(() => {
drawStore.unbindFormData(esbButtonModel);
});
function onUpdate() {
const esbButton = drawStore.selectedGraphic as EsbButton;

View File

@ -21,26 +21,21 @@
import { GatedBoxData } from 'src/drawApp/graphics/GatedBoxInteraction';
import { GatedBox } from 'src/graphics/gatedBox/GatedBox';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch } from 'vue';
import { onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const gatedBoxModel = reactive(new GatedBoxData());
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == GatedBox.Type) {
gatedBoxModel.copyFrom(val.saveData() as GatedBoxData);
}
}
);
onMounted(() => {
drawStore.bindFormData(gatedBoxModel);
const gatedBox = drawStore.selectedGraphic as GatedBox;
if (gatedBox) {
gatedBoxModel.copyFrom(gatedBox.saveData());
}
});
onUnmounted(() => {
drawStore.unbindFormData(gatedBoxModel);
});
function onUpdate() {
const gatedBox = drawStore.selectedGraphic as GatedBox;

View File

@ -53,21 +53,12 @@ import { Section } from 'src/graphics/section/Section';
import { Signal } from 'src/graphics/signal/Signal';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch, computed } from 'vue';
import { onMounted, reactive, computed, onUnmounted } from 'vue';
const drawStore = useDrawStore();
const linkModel = reactive(new LinkData());
const sectionList: { label: string; value: string }[] = reactive([]);
const portList = ['A', 'B', 'C'];
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == Link.Type) {
linkModel.copyFrom(val.saveData() as LinkData);
}
}
);
const aRelation = computed(() => {
const link = drawStore.selectedGraphic as Link;
@ -100,6 +91,7 @@ const deviceRelations = computed(() => {
});
onMounted(() => {
drawStore.bindFormData(linkModel);
const link = drawStore.selectedGraphic as Link;
const sections = drawStore
.getDrawApp()
@ -114,6 +106,9 @@ onMounted(() => {
linkModel.copyFrom(link.saveData());
}
});
onUnmounted(() => {
drawStore.unbindFormData(linkModel);
});
function onUpdate() {
const link = drawStore.selectedGraphic as Link;

View File

@ -51,27 +51,21 @@ import { LogicSectionData } from 'src/drawApp/graphics/LogicSectionInteraction';
import { AxleCountingSection } from 'src/graphics/axleCountingSection/AxleCountingSection';
import { LogicSection } from 'src/graphics/logicSection/LogicSection';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, watch } from 'vue';
import { computed, onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const logicSectionModel = reactive(new LogicSectionData());
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == LogicSection.Type) {
logicSectionModel.copyFrom(val.saveData() as LogicSectionData);
}
}
);
onMounted(() => {
drawStore.bindFormData(logicSectionModel);
const logicSection = drawStore.selectedGraphic as LogicSection;
if (logicSection) {
logicSectionModel.copyFrom(logicSection.saveData());
}
});
onUnmounted(() => {
drawStore.unbindFormData(logicSectionModel);
});
function onUpdate() {
const logicSection = drawStore.selectedGraphic as LogicSection;

View File

@ -36,7 +36,7 @@
import { PlatformData } from 'src/drawApp/graphics/PlatformInteraction';
import { Platform } from 'src/graphics/platform/Platform';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, ref, watch } from 'vue';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
const drawStore = useDrawStore();
const platformModel = reactive(new PlatformData());
@ -57,19 +57,8 @@ enum showSelectData {
down = '向下',
}
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == Platform.Type) {
platformModel.copyFrom(val.saveData() as PlatformData);
hasDoor.value = (showSelectData as never)[platformModel.hasdoor + ''];
direction.value = (showSelectData as never)[platformModel.direction];
}
}
);
onMounted(() => {
drawStore.bindFormData(platformModel);
const platform = drawStore.selectedGraphic as Platform;
if (platform) {
platformModel.copyFrom(platform.saveData());
@ -77,6 +66,9 @@ onMounted(() => {
direction.value = (showSelectData as never)[platformModel.direction];
}
});
onUnmounted(() => {
drawStore.unbindFormData(platformModel);
});
function onUpdate() {
platformModel.hasdoor = JSON.parse((showSelect as never)[hasDoor.value]);

View File

@ -19,7 +19,7 @@
import { SeparatorData } from 'src/drawApp/graphics/SeparatorInteraction';
import { Separator } from 'src/graphics/separator/Separator';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch } from 'vue';
import { onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const separatorModel = reactive(new SeparatorData());
@ -31,22 +31,16 @@ const typeOptions = [
{ label: '右断路分隔符', value: 'endB' },
];
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == Separator.Type) {
separatorModel.copyFrom(val.saveData() as SeparatorData);
}
}
);
onMounted(() => {
drawStore.bindFormData(separatorModel);
const Separator = drawStore.selectedGraphic as Separator;
if (Separator) {
separatorModel.copyFrom(Separator.saveData());
}
});
onUnmounted(() => {
drawStore.unbindFormData(separatorModel);
});
function onUpdate() {
const Separator = drawStore.selectedGraphic as Separator;

View File

@ -99,7 +99,7 @@ import { Direction, Signal } from 'src/graphics/signal/Signal';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch } from 'vue';
import { onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const signalModel = reactive(new SignalData());
@ -171,24 +171,18 @@ function initDeviceList() {
});
});
}
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == Signal.Type) {
initRefData(val as Signal);
}
}
);
onMounted(() => {
drawStore.bindFormData(signalModel);
const signal = drawStore.selectedGraphic as Signal;
if (signal) {
initDeviceList();
initRefData(signal);
}
});
onUnmounted(() => {
drawStore.unbindFormData(signalModel);
});
function onUpdate() {
const signal = drawStore.selectedGraphic as Signal;
signalModel.kilometerSystem = {

View File

@ -48,22 +48,14 @@ import { SpksSwitchData } from 'src/drawApp/graphics/SpksSwitchInteraction';
import { Section } from 'src/graphics/section/Section';
import { SpksSwitch } from 'src/graphics/spksSwitch/SpksSwitch';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch } from 'vue';
import { onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const spksSwitchModel = reactive(new SpksSwitchData());
const sectionList: { label: string; value: string }[] = reactive([]);
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == SpksSwitch.Type) {
spksSwitchModel.copyFrom(val.saveData() as SpksSwitchData);
}
}
);
onMounted(() => {
drawStore.bindFormData(spksSwitchModel);
const spksSwitch = drawStore.selectedGraphic as SpksSwitch;
const sections = drawStore
.getDrawApp()
@ -78,6 +70,9 @@ onMounted(() => {
spksSwitchModel.copyFrom(spksSwitch.saveData());
}
});
onUnmounted(() => {
drawStore.unbindFormData(spksSwitchModel);
});
function onUpdate() {
const spksSwitch = drawStore.selectedGraphic as SpksSwitch;

View File

@ -59,7 +59,7 @@
import { StationData } from 'src/drawApp/graphics/StationInteraction';
import { Station } from 'src/graphics/station/Station';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, ref, watch } from 'vue';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
const drawStore = useDrawStore();
const stationModel = reactive(new StationData());
@ -91,26 +91,8 @@ const directionOptions = [
{ label: '右行', value: 1 },
];
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == Station.Type) {
stationModel.copyFrom(val.saveData() as StationData);
concentrationStations.value = (showSelectData as never)[
stationModel.concentrationStations + ''
];
if (stationModel.kilometerSystem) {
kilometerSystem.coordinateSystem =
stationModel.kilometerSystem.coordinateSystem;
kilometerSystem.kilometer = stationModel.kilometerSystem.kilometer;
kilometerSystem.direction = stationModel.kilometerSystem.direction;
}
}
}
);
onMounted(() => {
drawStore.bindFormData(stationModel);
const station = drawStore.selectedGraphic as Station;
if (station) {
stationModel.copyFrom(station.saveData());
@ -125,6 +107,9 @@ onMounted(() => {
}
}
});
onUnmounted(() => {
drawStore.unbindFormData(stationModel);
});
function onUpdate() {
stationModel.concentrationStations = JSON.parse(

View File

@ -76,7 +76,7 @@ import {
} from 'src/graphics/stopPosition/StopPosition';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch } from 'vue';
import { onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const stopPositionModel = reactive(new StopPositionData());
@ -109,17 +109,9 @@ const optionsCoachNum = [
{ label: 6, value: CoachNum.Six },
{ label: 8, value: CoachNum.Eight },
];
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == StopPosition.Type) {
initRefData(val as StopPosition);
}
}
);
onMounted(() => {
drawStore.bindFormData(stopPositionModel);
const stopPosition = drawStore.selectedGraphic as StopPosition;
if (stopPosition) {
const sections = drawStore
@ -134,6 +126,9 @@ onMounted(() => {
initRefData(stopPosition);
}
});
onUnmounted(() => {
drawStore.unbindFormData(stopPositionModel);
});
function initRefData(stopPosition: StopPosition) {
stopPositionModel.copyFrom(stopPosition.saveData());

View File

@ -43,27 +43,21 @@ import { TrainWindowData } from 'src/drawApp/graphics/TrainWindowInteraction';
import { Section } from 'src/graphics/section/Section';
import { TrainWindow } from 'src/graphics/trainWindow/TrainWindow';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, watch } from 'vue';
import { computed, onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const trainWindowModel = reactive(new TrainWindowData());
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == TrainWindow.Type) {
trainWindowModel.copyFrom(val.saveData() as TrainWindowData);
}
}
);
onMounted(() => {
drawStore.bindFormData(trainWindowModel);
const trainWindow = drawStore.selectedGraphic as TrainWindow;
if (trainWindow) {
trainWindowModel.copyFrom(trainWindow.saveData());
}
});
onUnmounted(() => {
drawStore.unbindFormData(trainWindowModel);
});
function onUpdate() {
const trainWindow = drawStore.selectedGraphic as TrainWindow;

View File

@ -95,7 +95,7 @@ import {
} from 'src/graphics/transponder/Transponder';
import { Turnout } from 'src/graphics/turnout/Turnout';
import { useDrawStore } from 'src/stores/draw-store';
import { computed, onMounted, reactive, watch } from 'vue';
import { computed, onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const transponderModel = reactive(new TransponderData());
@ -124,27 +124,8 @@ const directionOptions = [
{ label: '右行', value: 1 },
];
drawStore.$subscribe;
watch(
() => drawStore.selectedGraphic,
(val) => {
if (val && val.type == Transponder.Type) {
transponderModel.copyFrom(val.saveData() as TransponderData);
if (transponderModel.kilometerSystem) {
kilometerSystem.coordinateSystem =
transponderModel.kilometerSystem.coordinateSystem;
kilometerSystem.kilometer = transponderModel.kilometerSystem.kilometer;
kilometerSystem.direction = transponderModel.kilometerSystem.direction;
} else {
kilometerSystem.coordinateSystem = '';
kilometerSystem.kilometer = 0;
kilometerSystem.direction = 0;
}
}
}
);
onMounted(() => {
drawStore.bindFormData(transponderModel);
const Transponder = drawStore.selectedGraphic as Transponder;
if (Transponder) {
transponderModel.copyFrom(Transponder.saveData());
@ -156,6 +137,9 @@ onMounted(() => {
}
}
});
onUnmounted(() => {
drawStore.unbindFormData(transponderModel);
});
function onUpdate() {
const Transponder = drawStore.selectedGraphic as Transponder;

View File

@ -10,7 +10,7 @@ import { state } from 'src/protos/device_state';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
import {
GraphicApp,
IGraphicScene,
GraphicInteractionPlugin,
JlGraphic,
} from 'src/jl-graphic';
@ -181,11 +181,11 @@ const PlatformOperateMenu: ContextMenu = ContextMenu.init({
export class PlatformOperateInteraction extends GraphicInteractionPlugin<Platform> {
static Name = 'platform_operate_menu';
constructor(app: GraphicApp) {
constructor(app: IGraphicScene) {
super(PlatformOperateInteraction.Name, app);
app.registerMenu(PlatformOperateMenu);
}
static init(app: GraphicApp) {
static init(app: IGraphicScene) {
return new PlatformOperateInteraction(app);
}
filter(...grahpics: JlGraphic[]): Platform[] | undefined {

View File

@ -4,8 +4,8 @@ import { ISectionData, Section } from 'src/graphics/section/Section';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { DisplayObject, FederatedMouseEvent, IPointData } from 'pixi.js';
import {
IGraphicApp,
GraphicInteractionPlugin,
IGraphicScene,
JlGraphic,
} from 'src/jl-graphic';
import { useLineStore } from 'src/stores/line-store';
@ -120,11 +120,11 @@ const SectionOperateMenu: ContextMenu = ContextMenu.init({
export class SectionOperateInteraction extends GraphicInteractionPlugin<Section> {
static Name = 'section_operate_menu';
constructor(app: IGraphicApp) {
constructor(app: IGraphicScene) {
super(SectionOperateInteraction.Name, app);
app.registerMenu(SectionOperateMenu);
}
static init(app: IGraphicApp) {
static init(app: IGraphicScene) {
return new SectionOperateInteraction(app);
}
filter(...grahpics: JlGraphic[]): Section[] | undefined {

View File

@ -7,7 +7,7 @@ import {
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { IPointData } from 'pixi.js';
import {
GraphicApp,
IGraphicScene,
GraphicInteractionPlugin,
JlGraphic,
} from 'src/jl-graphic';
@ -94,10 +94,10 @@ export class SectionLinkData
}
export class SectionLinkOperateInteraction extends GraphicInteractionPlugin<SectionLink> {
static Name = 'sectionLink_operate_menu';
constructor(app: GraphicApp) {
constructor(app: IGraphicScene) {
super(SectionLinkOperateInteraction.Name, app);
}
static init(app: GraphicApp) {
static init(app: IGraphicScene) {
return new SectionLinkOperateInteraction(app);
}
filter(...grahpics: JlGraphic[]): SectionLink[] | undefined {

View File

@ -9,7 +9,7 @@ import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
import {
GraphicInteractionPlugin,
GraphicApp,
IGraphicScene,
JlGraphic,
} from 'src/jl-graphic';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
@ -286,11 +286,11 @@ const SignalOperateMenu: ContextMenu = ContextMenu.init({
});
export class DrawSignalInteraction extends GraphicInteractionPlugin<Signal> {
static Name = 'signal_draw_right_menu';
constructor(app: GraphicApp) {
constructor(app: IGraphicScene) {
super(DrawSignalInteraction.Name, app);
app.registerMenu(SignalEditMenu);
}
static init(app: GraphicApp) {
static init(app: IGraphicScene) {
return new DrawSignalInteraction(app);
}
filter(...grahpics: JlGraphic[]): Signal[] | undefined {
@ -319,11 +319,11 @@ export class DrawSignalInteraction extends GraphicInteractionPlugin<Signal> {
export class SignalOperateInteraction extends GraphicInteractionPlugin<Signal> {
static Name = 'signal_operate_menu';
constructor(app: GraphicApp) {
constructor(app: IGraphicScene) {
super(SignalOperateInteraction.Name, app);
app.registerMenu(SignalOperateMenu);
}
static init(app: GraphicApp) {
static init(app: IGraphicScene) {
return new SignalOperateInteraction(app);
}
filter(...grahpics: JlGraphic[]): Signal[] | undefined {

View File

@ -10,7 +10,7 @@ import { state } from 'src/protos/device_state';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
import {
GraphicApp,
IGraphicScene,
GraphicInteractionPlugin,
JlGraphic,
} from 'src/jl-graphic';
@ -151,11 +151,11 @@ const StationOperateMenu: ContextMenu = ContextMenu.init({
export class StationOperateInteraction extends GraphicInteractionPlugin<Station> {
static Name = 'station_operate_menu';
constructor(app: GraphicApp) {
constructor(app: IGraphicScene) {
super(StationOperateInteraction.Name, app);
app.registerMenu(StationOperateMenu);
}
static init(app: GraphicApp) {
static init(app: IGraphicScene) {
return new StationOperateInteraction(app);
}
filter(...grahpics: JlGraphic[]): Station[] | undefined {

View File

@ -5,7 +5,7 @@ import { state } from 'src/protos/device_state';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
import {
IGraphicApp,
IGraphicScene,
GraphicInteractionPlugin,
JlGraphic,
} from 'src/jl-graphic';
@ -141,11 +141,11 @@ const TrainOperateMenu: ContextMenu = ContextMenu.init({
export class TrainOperateInteraction extends GraphicInteractionPlugin<Train> {
static Name = 'train_operate_menu';
constructor(app: IGraphicApp) {
constructor(app: IGraphicScene) {
super(TrainOperateInteraction.Name, app);
app.registerMenu(TrainOperateMenu);
}
static init(app: IGraphicApp) {
static init(app: IGraphicScene) {
return new TrainOperateInteraction(app);
}
filter(...grahpics: JlGraphic[]): Train[] | undefined {

View File

@ -11,7 +11,7 @@ import { DisplayObject, FederatedMouseEvent, IPointData } from 'pixi.js';
import { KilometerSystem } from 'src/graphics/signal/Signal';
import { state } from 'src/protos/device_state';
import {
IGraphicApp,
IGraphicScene,
GraphicInteractionPlugin,
JlGraphic,
} from 'src/jl-graphic';
@ -51,11 +51,11 @@ const TurnoutOperationMenu: ContextMenu = ContextMenu.init({
export class TurnoutOperationPlugin extends GraphicInteractionPlugin<Turnout> {
static Name = 'turnout_operate_menu';
constructor(app: IGraphicApp) {
constructor(app: IGraphicScene) {
super(TurnoutOperationPlugin.Name, app);
app.registerMenu(TurnoutOperationMenu);
}
static init(app: IGraphicApp) {
static init(app: IGraphicScene) {
return new TurnoutOperationPlugin(app);
}
filter(...grahpics: JlGraphic[]): Turnout[] | undefined {

View File

@ -1,120 +1,7 @@
import {
GraphicData,
GraphicState,
ClientEngine,
IGraphicApp,
newGraphicApp,
IGraphicStorage,
IdGenerator,
} from 'src/jl-graphic';
import { TrainState } from './graphics/TrainInteraction';
import { Train, TrainTemplate } from 'src/graphics/train/Train';
import { TrainOperateInteraction } from './graphics/TrainInteraction';
import {
SignalData,
SignalOperateInteraction,
SignalState,
} from './graphics/SignalInteraction';
import { SignalTemplate, Signal } from 'src/graphics/signal/Signal';
import {
PlatformData,
PlatformOperateInteraction,
PlatformState,
} from './graphics/PlatformInteraction';
import { PlatformTemplate, Platform } from 'src/graphics/platform/Platform';
import {
StationData,
StationOperateInteraction,
StationState,
} from './graphics/StationInteraction';
import { Station, StationTemplate } from 'src/graphics/station/Station';
import {
TurnoutData,
TurnoutOperationPlugin,
TurnoutStates,
} from './graphics/TurnoutInteraction';
import { Turnout, TurnoutTemplate } from 'src/graphics/turnout/Turnout';
import {
SectionData,
SectionOperateInteraction,
} from './graphics/SectionInteraction';
import { Section, SectionTemplate } from 'src/graphics/section/Section';
import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { useLineStore } from 'src/stores/line-store';
import { toUint8Array } from 'js-base64';
import { getWebsocketUrl } from 'src/configs/UrlManage';
import { getOnlyToken } from 'src/configs/TokenManage';
import { state } from 'src/protos/device_state';
import {
AxleCounting,
AxleCountingTemplate,
} from 'src/graphics/axleCounting/AxleCounting';
import { AxleCountingData } from './graphics/AxleCountingInteraction';
import {
TrainWindow,
TrainWindowTemplate,
} from 'src/graphics/trainWindow/TrainWindow';
import { TrainWindowData } from './graphics/TrainWindowInteraction';
import { useRoute } from 'vue-router';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
import {
AxleCountingSection,
AxleCountingSectionTemplate,
} from 'src/graphics/axleCountingSection/AxleCountingSection';
import {
LogicSection,
LogicSectionTemplate,
} from 'src/graphics/logicSection/LogicSection';
import {
SectionLink,
SectionLinkTemplate,
} from 'src/graphics/sectionLink/SectionLink';
import { Separator, SeparatorTemplate } from 'src/graphics/separator/Separator';
import { SeparatorData } from './graphics/SeparatorInteraction';
import {
SectionLinkData,
SectionLinkOperateInteraction,
} from './graphics/SectionLinkInteraction';
import { AxleCountingSectionData } from './graphics/AxleCountingSectionInteraction';
import { LogicSectionData } from './graphics/LogicSectionInteraction';
import { Notify, QNotifyUpdateOptions } from 'quasar';
import {
StopPosition,
StopPositionTemplate,
} from 'src/graphics/stopPosition/StopPosition';
import {
SpksSwitch,
SpksSwitchTemplate,
} from 'src/graphics/spksSwitch/SpksSwitch';
import { GatedBox, GatedBoxTemplate } from 'src/graphics/gatedBox/GatedBox';
import { EsbButton, EsbButtonTemplate } from 'src/graphics/esbButton/EsbButton';
import { StopPositionData } from './graphics/StopPositionInteraction';
import { SpksSwitchData } from './graphics/SpksSwitchInteraction';
import { GatedBoxData } from './graphics/GatedBoxInteraction';
import { EsbButtonData } from './graphics/EsbButtonInteraction';
import {
Transponder,
TransponderTemplate,
} from 'src/graphics/transponder/Transponder';
import { TransponderData } from './graphics/TransponderInteraction';
import {
SlopeKiloMarker,
SlopeKiloMarkerTemplate,
} from 'src/graphics/slopeKiloMarker/SlopeKiloMarker';
import { SlopeKiloMarkerData } from './graphics/SlopeKiloMarkerInteraction';
import { Link, LinkTemplate } from 'src/graphics/link/Link';
import { LinkData } from './graphics/LinkInteraction';
import { Slope, SlopeTemplate } from 'src/graphics/slope/Slope';
import {
CurvatureKiloMarker,
CurvatureKiloMarkerTemplate,
} from 'src/graphics/curvatureKiloMarker/CurvatureKiloMarker';
import { Curvature, CurvatureTemplate } from 'src/graphics/curvature/Curvature';
import { SlopeData } from './graphics/SlopeInteraction';
import { CurvatureKiloMarkerData } from './graphics/CurvatureKiloMarkerInteraction';
import { CurvatureData } from './graphics/CurvatureInteraction';
import { IGraphicApp, newGraphicApp } from 'src/jl-graphic';
import { initRelayScene } from './relayScene';
import { initLineScene } from './lineScene';
import { initPslScene } from './pslScene';
let lineApp: IGraphicApp | null = null;
@ -129,334 +16,18 @@ export function destroyLineApp(): void {
}
}
const showOptions: MenuItemOptions = {
name: '显示控制',
};
const DefaultCanvasMenu = new ContextMenu({
name: '图层选择',
groups: [
{
items: [showOptions],
},
],
});
export const layerList = [
// 图层列表 默认显示的图层defaultShow: true
{ label: '区段', value: Section.Type, defaultShow: true },
{ label: 'SectionLink', value: SectionLink.Type, defaultShow: false },
{ label: '区段检测点', value: AxleCounting.Type, defaultShow: false },
{ label: '站台', value: Platform.Type, defaultShow: true },
{ label: '车站', value: Station.Type, defaultShow: true },
{ label: '道岔', value: Turnout.Type, defaultShow: true },
{ label: '信号机', value: Signal.Type, defaultShow: true },
{ label: '分隔符', value: Separator.Type, defaultShow: true },
{ label: '列车', value: Train.Type, defaultShow: true },
{ label: '停车位置标', value: StopPosition.Type, defaultShow: true },
{ label: 'Spks开关', value: SpksSwitch.Type, defaultShow: true },
{ label: '门控箱', value: GatedBox.Type, defaultShow: true },
{ label: '紧急关闭按钮', value: EsbButton.Type, defaultShow: true },
{ label: '应答器', value: Transponder.Type, defaultShow: true },
{ label: 'Link', value: Link.Type, defaultShow: false },
{ label: '车次窗', value: TrainWindow.Type, defaultShow: false },
{ label: '计轴区段', value: AxleCountingSection.Type, defaultShow: false },
{ label: '逻辑区段', value: LogicSection.Type, defaultShow: false },
{ label: '坡度公里标', value: SlopeKiloMarker.Type, defaultShow: false },
{ label: '坡度', value: Slope.Type, defaultShow: false },
{ label: '曲度公里标', value: CurvatureKiloMarker.Type, defaultShow: false },
{ label: '曲度', value: Curvature.Type, defaultShow: false },
];
export function initLineApp(): IGraphicApp {
lineApp = newGraphicApp({
dataLoader: loadLineDatas,
mouseToolOptions: {
boxSelect: false,
viewportDrag: true,
wheelZoom: true,
},
});
lineApp.initScene('lineApp', {});
const graphicTemplate = [
new TrainTemplate(new TrainState()),
new SignalTemplate(new SignalData(), new SignalState()),
new PlatformTemplate(new PlatformData(), new PlatformState()),
new StationTemplate(new StationData(), new StationState()),
new TurnoutTemplate(new TurnoutData(), new TurnoutStates()),
new SectionTemplate(new SectionData()),
new AxleCountingTemplate(new AxleCountingData()),
new TrainWindowTemplate(new TrainWindowData()),
new SeparatorTemplate(new SeparatorData()),
new SectionLinkTemplate(new SectionLinkData()),
new AxleCountingSectionTemplate(new AxleCountingSectionData()),
new LogicSectionTemplate(new LogicSectionData()),
new StopPositionTemplate(new StopPositionData()),
new SpksSwitchTemplate(new SpksSwitchData()),
new GatedBoxTemplate(new GatedBoxData()),
new EsbButtonTemplate(new EsbButtonData()),
new TransponderTemplate(new TransponderData()),
new SlopeKiloMarkerTemplate(new SlopeKiloMarkerData()),
new LinkTemplate(new LinkData()),
new TrainWindowTemplate(new TrainWindowData()),
new SlopeTemplate(new SlopeData()),
new CurvatureKiloMarkerTemplate(new CurvatureKiloMarkerData()),
new CurvatureTemplate(new CurvatureData()),
];
lineApp.registerGraphicTemplates(...graphicTemplate);
lineApp.setOptions({
interactiveGraphicTypeIncludes: [
Signal.Type,
Platform.Type,
Station.Type,
SectionLink.Type,
Train.Type,
Turnout.Type,
Section.Type,
Transponder.Type,
],
});
SignalOperateInteraction.init(lineApp);
PlatformOperateInteraction.init(lineApp);
StationOperateInteraction.init(lineApp);
SectionLinkOperateInteraction.init(lineApp);
SectionOperateInteraction.init(lineApp);
TrainOperateInteraction.init(lineApp);
TurnoutOperationPlugin.init(lineApp);
// 画布右键菜单
lineApp.registerMenu(DefaultCanvasMenu);
lineApp.canvas.on('_rightclick', (e) => {
const lineStore = useLineStore();
showOptions.handler = () => {
lineStore.setShowLayerDialog(true);
};
DefaultCanvasMenu.open(e.global);
});
lineApp.on('postdataloaded', () => {
ControlShowType();
handleSubscribe();
});
lineApp = newGraphicApp({});
initLineScene(lineApp);
// PSL
initPslScene(lineApp);
// 继电器
initRelayScene(lineApp);
return lineApp;
}
function handleSubscribe() {
const lineStore = useLineStore();
const simulationId = lineStore.simulationId;
const app = lineStore.getLineApp();
app.enableWsMassaging({
engine: ClientEngine.Centrifugo,
wsUrl: `${getWebsocketUrl()}`,
token: getOnlyToken() as string,
});
app.subscribe({
// destination: `/simulation/${simulationId}/devices/status`,
destination: `simulation-${simulationId}-devices-status`,
messageConverter: (message: Uint8Array) => {
// console.log('收到消息', message);
const states: GraphicState[] = [];
const storage = state.PushedDevicesStatus.deserialize(message);
if (storage.all) {
storage.allStatus.sectionState.forEach((item) => {
if (state.SectionType[item.type] == 'Axle') {
//计轴区段
// states.push(new AxleCountingState(item));
} else if (state.SectionType[item.type] == 'Logic') {
// 逻辑区段
// states.push(new LogicSectionState(item));
} else if (state.SectionType[item.type] == 'Physic') {
// 物理区段
// states.push(new SectionState(item));
}
});
storage.allStatus.switchState.forEach((item) => {
// 道岔
states.push(new TurnoutStates(item));
});
storage.allStatus.trainState.forEach((item) => {
// 列车
if (!item.show) {
// 移除列车
const train = app.queryStore.queryByCodeAndType(
item.id,
Train.Type
);
if (train) {
app.deleteGraphics(train);
}
} else {
states.push(new TrainState(item));
}
});
} else {
storage.varStatus.updatedSection.forEach((item) => {
if (state.SectionType[item.type] == 'Axle') {
//计轴区段
// states.push(new AxleCountingState(item));
} else if (state.SectionType[item.type] == 'Logic') {
// 逻辑区段
// states.push(new LogicSectionState(item));
} else if (state.SectionType[item.type] == 'Physic') {
// 物理区段
// states.push(new SectionState(item));
}
});
storage.varStatus.updatedSwitch.forEach((item) => {
// 道岔
states.push(new TurnoutStates(item));
});
storage.varStatus.updatedTrain.forEach((item) => {
// 列车
states.push(new TrainState(item));
});
storage.varStatus.removedTrainId.forEach((item) => {
// 移除列车
const train = app.queryStore.queryByCodeAndType(item, Train.Type);
if (train) {
app.deleteGraphics(train);
}
});
}
if (states && states.length > 0) {
lineStore.setSocketStates(states);
}
return states;
},
});
let msgNotify: null | ((props?: QNotifyUpdateOptions | undefined) => void) =
null;
app.on('websocket-connect-state-change', (connected) => {
if (!connected && !msgNotify) {
msgNotify = Notify.create({
type: 'negative',
timeout: 0,
position: 'top-right',
message: '通信链接已断开!',
});
} else if (msgNotify && connected) {
msgNotify();
msgNotify = null;
}
});
}
function ControlShowType() {
const lineStore = useLineStore();
const showTypeList: string[] = [];
layerList.forEach((item) => {
if (item.defaultShow) {
showTypeList.push(item.value);
}
});
if (lineApp) {
const alllGraphic = (lineApp as IGraphicApp).queryStore.getAllGraphics();
alllGraphic.forEach((g) => {
if (showTypeList.includes(g.type)) {
g.visible = true;
} else {
g.visible = false;
}
if (g.type == Transponder.Type) {
// 应答器不显示名称
(g as Transponder).labelGraphic.visible = false;
}
});
lineStore.setShowLayer(showTypeList);
}
}
export async function loadLineDatas(): Promise<IGraphicStorage> {
const route = useRoute();
const mapId = route.query.mapId as string;
const simulationId = route.query.simulationId;
if (!mapId || !simulationId) {
throw new Error('获取数据异常为获取到地图ID或仿真ID');
}
const { proto: base64 } = await getPublishMapInfoByLineId(mapId);
if (base64) {
const storage = graphicData.RtssGraphicStorage.deserialize(
toUint8Array(base64)
);
console.log('加载数据', storage);
// app.updateCanvas(storage.canvas);
const datas: GraphicData[] = [];
storage.Platforms.forEach((platform) => {
const g = new PlatformData(platform);
datas.push(g);
});
storage.stations.forEach((station) => {
datas.push(new StationData(station));
});
storage.turnouts.forEach((turnout) => {
datas.push(new TurnoutData(turnout));
});
storage.signals.forEach((signal) => {
datas.push(new SignalData(signal));
});
storage.section.forEach((section) => {
datas.push(new SectionData(section));
});
storage.axleCountings.forEach((axleCounting) => {
datas.push(new AxleCountingData(axleCounting));
});
storage.trainWindows.forEach((trainWindow) => {
datas.push(new TrainWindowData(trainWindow));
});
storage.separators.forEach((separator) => {
datas.push(new SeparatorData(separator));
});
storage.sectionLinks.forEach((sectionLink) => {
datas.push(new SectionLinkData(sectionLink));
});
storage.axleCountingSections.forEach((axleCountingSection) => {
datas.push(new AxleCountingSectionData(axleCountingSection));
});
storage.logicSections.forEach((logicSection) => {
datas.push(new LogicSectionData(logicSection));
});
storage.stopPositions.forEach((stopPosition) => {
datas.push(new StopPositionData(stopPosition));
});
storage.spksSwitchs.forEach((spksSwitch) => {
datas.push(new SpksSwitchData(spksSwitch));
});
storage.gateBoxs.forEach((gateBox) => {
datas.push(new GatedBoxData(gateBox));
});
storage.esbButtons.forEach((esbButton) => {
datas.push(new EsbButtonData(esbButton));
});
storage.transponders.forEach((transponder) => {
datas.push(new TransponderData(transponder));
});
storage.slopeKiloMarker.forEach((slopeKilometer) => {
datas.push(new SlopeKiloMarkerData(slopeKilometer));
});
storage.curvatureKiloMarker.forEach((curvatureKiloMarker) => {
datas.push(new CurvatureKiloMarkerData(curvatureKiloMarker));
});
storage.slopes.forEach((slope) => {
datas.push(new SlopeData(slope));
});
storage.curvatures.forEach((curvature) => {
datas.push(new CurvatureData(curvature));
});
const linkIdGenerator = new IdGenerator(Link.Type);
storage.CalculateLink.forEach((link) => {
const g = new LinkData(link);
g.id = linkIdGenerator.next();
datas.push(g);
});
// await app.loadGraphic(datas);
return Promise.resolve({
canvasProperty: storage.canvas,
datas: datas,
});
} else {
return Promise.resolve({
datas: [],
});
}
export enum SceneToPictureType { // 场景对应类型
lineScene = 'lineScene',
pslScene = 'pslScene',
relayScene = 'relayScene',
}

449
src/drawApp/lineScene.ts Normal file
View File

@ -0,0 +1,449 @@
import {
GraphicData,
GraphicState,
ClientEngine,
IGraphicApp,
IGraphicStorage,
IdGenerator,
} from 'src/jl-graphic';
import { TrainState } from './graphics/TrainInteraction';
import { Train, TrainTemplate } from 'src/graphics/train/Train';
import { TrainOperateInteraction } from './graphics/TrainInteraction';
import {
SignalData,
SignalOperateInteraction,
SignalState,
} from './graphics/SignalInteraction';
import { SignalTemplate, Signal } from 'src/graphics/signal/Signal';
import {
PlatformData,
PlatformOperateInteraction,
PlatformState,
} from './graphics/PlatformInteraction';
import { PlatformTemplate, Platform } from 'src/graphics/platform/Platform';
import {
StationData,
StationOperateInteraction,
StationState,
} from './graphics/StationInteraction';
import { Station, StationTemplate } from 'src/graphics/station/Station';
import {
TurnoutData,
TurnoutOperationPlugin,
TurnoutStates,
} from './graphics/TurnoutInteraction';
import { Turnout, TurnoutTemplate } from 'src/graphics/turnout/Turnout';
import {
SectionData,
SectionOperateInteraction,
} from './graphics/SectionInteraction';
import { Section, SectionTemplate } from 'src/graphics/section/Section';
import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { useLineStore } from 'src/stores/line-store';
import { toUint8Array } from 'js-base64';
import { getWebsocketUrl } from 'src/configs/UrlManage';
import { getOnlyToken } from 'src/configs/TokenManage';
import { state } from 'src/protos/device_state';
import {
AxleCounting,
AxleCountingTemplate,
} from 'src/graphics/axleCounting/AxleCounting';
import { AxleCountingData } from './graphics/AxleCountingInteraction';
import {
TrainWindow,
TrainWindowTemplate,
} from 'src/graphics/trainWindow/TrainWindow';
import { TrainWindowData } from './graphics/TrainWindowInteraction';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
import {
AxleCountingSection,
AxleCountingSectionTemplate,
} from 'src/graphics/axleCountingSection/AxleCountingSection';
import {
LogicSection,
LogicSectionTemplate,
} from 'src/graphics/logicSection/LogicSection';
import {
SectionLink,
SectionLinkTemplate,
} from 'src/graphics/sectionLink/SectionLink';
import { Separator, SeparatorTemplate } from 'src/graphics/separator/Separator';
import { SeparatorData } from './graphics/SeparatorInteraction';
import {
SectionLinkData,
SectionLinkOperateInteraction,
} from './graphics/SectionLinkInteraction';
import { AxleCountingSectionData } from './graphics/AxleCountingSectionInteraction';
import { LogicSectionData } from './graphics/LogicSectionInteraction';
import { Notify, QNotifyUpdateOptions } from 'quasar';
import {
StopPosition,
StopPositionTemplate,
} from 'src/graphics/stopPosition/StopPosition';
import {
SpksSwitch,
SpksSwitchTemplate,
} from 'src/graphics/spksSwitch/SpksSwitch';
import { GatedBox, GatedBoxTemplate } from 'src/graphics/gatedBox/GatedBox';
import { EsbButton, EsbButtonTemplate } from 'src/graphics/esbButton/EsbButton';
import { StopPositionData } from './graphics/StopPositionInteraction';
import { SpksSwitchData } from './graphics/SpksSwitchInteraction';
import { GatedBoxData } from './graphics/GatedBoxInteraction';
import { EsbButtonData } from './graphics/EsbButtonInteraction';
import {
Transponder,
TransponderTemplate,
} from 'src/graphics/transponder/Transponder';
import { TransponderData } from './graphics/TransponderInteraction';
import {
SlopeKiloMarker,
SlopeKiloMarkerTemplate,
} from 'src/graphics/slopeKiloMarker/SlopeKiloMarker';
import { SlopeKiloMarkerData } from './graphics/SlopeKiloMarkerInteraction';
import { Link, LinkTemplate } from 'src/graphics/link/Link';
import { LinkData } from './graphics/LinkInteraction';
import { Slope, SlopeTemplate } from 'src/graphics/slope/Slope';
import {
CurvatureKiloMarker,
CurvatureKiloMarkerTemplate,
} from 'src/graphics/curvatureKiloMarker/CurvatureKiloMarker';
import { Curvature, CurvatureTemplate } from 'src/graphics/curvature/Curvature';
import { SlopeData } from './graphics/SlopeInteraction';
import { CurvatureKiloMarkerData } from './graphics/CurvatureKiloMarkerInteraction';
import { CurvatureData } from './graphics/CurvatureInteraction';
import {
GraphicAppOptions,
IGraphicScene,
} from 'src/jl-graphic/app/JlGraphicApp';
import { SceneToPictureType } from './lineApp';
const showOptions: MenuItemOptions = {
name: '显示控制',
};
const DefaultCanvasMenu = new ContextMenu({
name: '图层选择',
groups: [
{
items: [showOptions],
},
],
});
export const layerList = [
// 图层列表 默认显示的图层defaultShow: true
{ label: '区段', value: Section.Type, defaultShow: true },
{ label: 'SectionLink', value: SectionLink.Type, defaultShow: false },
{ label: '区段检测点', value: AxleCounting.Type, defaultShow: false },
{ label: '站台', value: Platform.Type, defaultShow: true },
{ label: '车站', value: Station.Type, defaultShow: true },
{ label: '道岔', value: Turnout.Type, defaultShow: true },
{ label: '信号机', value: Signal.Type, defaultShow: true },
{ label: '分隔符', value: Separator.Type, defaultShow: true },
{ label: '列车', value: Train.Type, defaultShow: true },
{ label: '停车位置标', value: StopPosition.Type, defaultShow: true },
{ label: 'Spks开关', value: SpksSwitch.Type, defaultShow: true },
{ label: '门控箱', value: GatedBox.Type, defaultShow: true },
{ label: '紧急关闭按钮', value: EsbButton.Type, defaultShow: true },
{ label: '应答器', value: Transponder.Type, defaultShow: true },
{ label: 'Link', value: Link.Type, defaultShow: false },
{ label: '车次窗', value: TrainWindow.Type, defaultShow: false },
{ label: '计轴区段', value: AxleCountingSection.Type, defaultShow: false },
{ label: '逻辑区段', value: LogicSection.Type, defaultShow: false },
{ label: '坡度公里标', value: SlopeKiloMarker.Type, defaultShow: false },
{ label: '坡度', value: Slope.Type, defaultShow: false },
{ label: '曲度公里标', value: CurvatureKiloMarker.Type, defaultShow: false },
{ label: '曲度', value: Curvature.Type, defaultShow: false },
];
export function initLineScene(lineApp: IGraphicApp) {
const options: GraphicAppOptions = {
dataLoader: loadLineDatas,
mouseToolOptions: {
boxSelect: false,
viewportDrag: true,
wheelZoom: true,
},
interactiveGraphicTypeIncludes: [
Signal.Type,
Platform.Type,
Station.Type,
SectionLink.Type,
Train.Type,
Turnout.Type,
Section.Type,
Transponder.Type,
],
};
const lineScene = lineApp.initScene(SceneToPictureType.lineScene, options);
const graphicTemplate = [
new TrainTemplate(new TrainState()),
new SignalTemplate(new SignalData(), new SignalState()),
new PlatformTemplate(new PlatformData(), new PlatformState()),
new StationTemplate(new StationData(), new StationState()),
new TurnoutTemplate(new TurnoutData(), new TurnoutStates()),
new SectionTemplate(new SectionData()),
new AxleCountingTemplate(new AxleCountingData()),
new TrainWindowTemplate(new TrainWindowData()),
new SeparatorTemplate(new SeparatorData()),
new SectionLinkTemplate(new SectionLinkData()),
new AxleCountingSectionTemplate(new AxleCountingSectionData()),
new LogicSectionTemplate(new LogicSectionData()),
new StopPositionTemplate(new StopPositionData()),
new SpksSwitchTemplate(new SpksSwitchData()),
new GatedBoxTemplate(new GatedBoxData()),
new EsbButtonTemplate(new EsbButtonData()),
new TransponderTemplate(new TransponderData()),
new SlopeKiloMarkerTemplate(new SlopeKiloMarkerData()),
new LinkTemplate(new LinkData()),
new TrainWindowTemplate(new TrainWindowData()),
new SlopeTemplate(new SlopeData()),
new CurvatureKiloMarkerTemplate(new CurvatureKiloMarkerData()),
new CurvatureTemplate(new CurvatureData()),
];
lineScene.registerGraphicTemplates(...graphicTemplate);
SignalOperateInteraction.init(lineScene);
PlatformOperateInteraction.init(lineScene);
StationOperateInteraction.init(lineScene);
SectionLinkOperateInteraction.init(lineScene);
SectionOperateInteraction.init(lineScene);
TrainOperateInteraction.init(lineScene);
TurnoutOperationPlugin.init(lineScene);
// 画布右键菜单
lineScene.registerMenu(DefaultCanvasMenu);
lineScene.canvas.on('_rightclick', (e) => {
const lineStore = useLineStore();
showOptions.handler = () => {
lineStore.setShowLayerDialog(true);
};
DefaultCanvasMenu.open(e.global);
});
lineScene.on('postdataloaded', () => {
ControlShowType(lineScene);
handleSubscribe(lineScene, lineApp);
});
}
function handleSubscribe(lineScene: IGraphicScene, lineApp: IGraphicApp) {
const lineStore = useLineStore();
const simulationId = lineStore.simulationId;
const app = lineScene;
lineApp?.enableWsMassaging({
engine: ClientEngine.Centrifugo,
wsUrl: `${getWebsocketUrl()}`,
token: getOnlyToken() as string,
});
app.subscribe({
// destination: `/simulation/${simulationId}/devices/status`,
destination: `simulation-${simulationId}-devices-status`,
messageConverter: (message: Uint8Array) => {
// console.log('收到消息', message);
const states: GraphicState[] = [];
const storage = state.PushedDevicesStatus.deserialize(message);
if (storage.all) {
storage.allStatus.sectionState.forEach((item) => {
if (state.SectionType[item.type] == 'Axle') {
//计轴区段
// states.push(new AxleCountingState(item));
} else if (state.SectionType[item.type] == 'Logic') {
// 逻辑区段
// states.push(new LogicSectionState(item));
} else if (state.SectionType[item.type] == 'Physic') {
// 物理区段
// states.push(new SectionState(item));
}
});
storage.allStatus.switchState.forEach((item) => {
// 道岔
states.push(new TurnoutStates(item));
});
storage.allStatus.trainState.forEach((item) => {
// 列车
if (!item.show) {
// 移除列车
const train = app.queryStore.queryByCodeAndType(
item.id,
Train.Type
);
if (train) {
app.deleteGraphics(train);
}
} else {
states.push(new TrainState(item));
}
});
} else {
storage.varStatus.updatedSection.forEach((item) => {
if (state.SectionType[item.type] == 'Axle') {
//计轴区段
// states.push(new AxleCountingState(item));
} else if (state.SectionType[item.type] == 'Logic') {
// 逻辑区段
// states.push(new LogicSectionState(item));
} else if (state.SectionType[item.type] == 'Physic') {
// 物理区段
// states.push(new SectionState(item));
}
});
storage.varStatus.updatedSwitch.forEach((item) => {
// 道岔
states.push(new TurnoutStates(item));
});
storage.varStatus.updatedTrain.forEach((item) => {
// 列车
states.push(new TrainState(item));
});
storage.varStatus.removedTrainId.forEach((item) => {
// 移除列车
const train = app.queryStore.queryByCodeAndType(item, Train.Type);
if (train) {
app.deleteGraphics(train);
}
});
}
if (states && states.length > 0) {
lineStore.setSocketStates(states);
}
return states;
},
});
let msgNotify: null | ((props?: QNotifyUpdateOptions | undefined) => void) =
null;
app.on('websocket-connect-state-change', (connected) => {
if (!connected && !msgNotify) {
msgNotify = Notify.create({
type: 'negative',
timeout: 0,
position: 'top-right',
message: '通信链接已断开!',
});
} else if (msgNotify && connected) {
msgNotify();
msgNotify = null;
}
});
}
function ControlShowType(lineScene: IGraphicScene) {
const lineStore = useLineStore();
const showTypeList: string[] = [];
layerList.forEach((item) => {
if (item.defaultShow) {
showTypeList.push(item.value);
}
});
if (lineScene) {
const alllGraphic = lineScene.queryStore.getAllGraphics();
alllGraphic.forEach((g) => {
if (showTypeList.includes(g.type)) {
g.visible = true;
} else {
g.visible = false;
}
if (g.type == Transponder.Type) {
// 应答器不显示名称
(g as Transponder).labelGraphic.visible = false;
}
});
lineStore.setShowLayer(showTypeList);
}
}
export async function loadLineDatas(): Promise<IGraphicStorage> {
const lineStore = useLineStore();
const mapId = lineStore.mapId;
const simulationId = lineStore.simulationId;
if (!mapId || !simulationId) {
throw new Error('获取数据异常未获取到地图ID或仿真ID');
}
const { proto: base64 } = await getPublishMapInfoByLineId(mapId + '');
if (base64) {
const storage = graphicData.RtssGraphicStorage.deserialize(
toUint8Array(base64)
);
console.log('加载数据', storage);
// app.updateCanvas(storage.canvas);
const datas: GraphicData[] = [];
storage.Platforms.forEach((platform) => {
const g = new PlatformData(platform);
datas.push(g);
});
storage.stations.forEach((station) => {
datas.push(new StationData(station));
});
storage.turnouts.forEach((turnout) => {
datas.push(new TurnoutData(turnout));
});
storage.signals.forEach((signal) => {
datas.push(new SignalData(signal));
});
storage.section.forEach((section) => {
datas.push(new SectionData(section));
});
storage.axleCountings.forEach((axleCounting) => {
datas.push(new AxleCountingData(axleCounting));
});
storage.trainWindows.forEach((trainWindow) => {
datas.push(new TrainWindowData(trainWindow));
});
storage.separators.forEach((separator) => {
datas.push(new SeparatorData(separator));
});
storage.sectionLinks.forEach((sectionLink) => {
datas.push(new SectionLinkData(sectionLink));
});
storage.axleCountingSections.forEach((axleCountingSection) => {
datas.push(new AxleCountingSectionData(axleCountingSection));
});
storage.logicSections.forEach((logicSection) => {
datas.push(new LogicSectionData(logicSection));
});
storage.stopPositions.forEach((stopPosition) => {
datas.push(new StopPositionData(stopPosition));
});
storage.spksSwitchs.forEach((spksSwitch) => {
datas.push(new SpksSwitchData(spksSwitch));
});
storage.gateBoxs.forEach((gateBox) => {
datas.push(new GatedBoxData(gateBox));
});
storage.esbButtons.forEach((esbButton) => {
datas.push(new EsbButtonData(esbButton));
});
storage.transponders.forEach((transponder) => {
datas.push(new TransponderData(transponder));
});
storage.slopeKiloMarker.forEach((slopeKilometer) => {
datas.push(new SlopeKiloMarkerData(slopeKilometer));
});
storage.curvatureKiloMarker.forEach((curvatureKiloMarker) => {
datas.push(new CurvatureKiloMarkerData(curvatureKiloMarker));
});
storage.slopes.forEach((slope) => {
datas.push(new SlopeData(slope));
});
storage.curvatures.forEach((curvature) => {
datas.push(new CurvatureData(curvature));
});
const linkIdGenerator = new IdGenerator(Link.Type);
storage.CalculateLink.forEach((link) => {
const g = new LinkData(link);
g.id = linkIdGenerator.next();
datas.push(g);
});
// await app.loadGraphic(datas);
return Promise.resolve({
canvasProperty: storage.canvas,
datas: datas,
});
} else {
return Promise.resolve({
datas: [],
});
}
}

64
src/drawApp/pslScene.ts Normal file
View File

@ -0,0 +1,64 @@
import { GraphicData, IGraphicApp, IGraphicStorage } from 'src/jl-graphic';
import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
import { useLineStore } from 'src/stores/line-store';
import { toUint8Array } from 'js-base64';
import { PslKeyTemplate } from 'src/graphics/pslKey/pslKey';
import { PslKeyData } from './graphics/PslKeyInteraction';
import { PslButtonTemplate } from 'src/graphics/pslButton/pslButton';
import { PslButtonData } from './graphics/PslButtonInteraction';
import { PslLightTemplate } from 'src/graphics/pslLight/pslLight';
import { PslLightData } from './graphics/PslLightInteraction';
import { pslGraphicData } from 'src/protos/pslGraphics';
import { SceneToPictureType } from './lineApp';
export function initPslScene(lineApp: IGraphicApp) {
// psl
const pslScene = lineApp.initScene(SceneToPictureType.pslScene, {
dataLoader: loadPslDatas,
mouseToolOptions: {
boxSelect: false,
viewportDrag: true,
wheelZoom: true,
},
});
const graphicTemplate = [
new PslKeyTemplate(new PslKeyData()),
new PslButtonTemplate(new PslButtonData()),
new PslLightTemplate(new PslLightData()),
];
pslScene.registerGraphicTemplates(...graphicTemplate);
return lineApp;
}
async function loadPslDatas(): Promise<IGraphicStorage> {
const lineStore = useLineStore();
const mapId = lineStore.mapId;
const simulationId = lineStore.simulationId;
if (!mapId || !simulationId) {
throw new Error('获取数据异常未获取到地图ID或仿真ID');
}
const { proto: base64 } = await getPublishMapInfoByLineId(mapId + '');
if (base64) {
const storage = pslGraphicData.PslGraphicStorage.deserialize(
toUint8Array(base64)
);
const datas: GraphicData[] = [];
storage.pslLights.forEach((pslLight) => {
datas.push(new PslLightData(pslLight));
});
storage.pslButtons.forEach((pslButton) => {
datas.push(new PslButtonData(pslButton));
});
storage.pslKeys.forEach((pslKey) => {
datas.push(new PslKeyData(pslKey));
});
return Promise.resolve({
canvasProperty: storage.canvas,
datas: datas,
});
} else {
return Promise.resolve({
datas: [],
});
}
}

59
src/drawApp/relayScene.ts Normal file
View File

@ -0,0 +1,59 @@
import { GraphicData, IGraphicApp, IGraphicStorage } from 'src/jl-graphic';
import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
import { useLineStore } from 'src/stores/line-store';
import { toUint8Array } from 'js-base64';
import { relayCabinetGraphicData } from 'src/protos/relayCabinetLayoutGraphics';
import { RelayCabinetData } from './relayCabinetGraphics/RelayCabinetInteraction';
import { RelayData } from './relayCabinetGraphics/RelayInteraction';
import { RelayCabinetTemplate } from 'src/graphics/relayCabinet/RelayCabinet';
import { RelayTemplate } from 'src/graphics/relay/Relay';
import { SceneToPictureType } from './lineApp';
export function initRelayScene(lineApp: IGraphicApp) {
// 继电器
const relayScene = lineApp.initScene(SceneToPictureType.relayScene, {
dataLoader: loadRelayDatas,
mouseToolOptions: {
boxSelect: false,
viewportDrag: true,
wheelZoom: true,
},
});
const relayGraphicTemplate = [
new RelayCabinetTemplate(new RelayCabinetData()),
new RelayTemplate(new RelayData()),
];
relayScene.registerGraphicTemplates(...relayGraphicTemplate);
return lineApp;
}
async function loadRelayDatas(): Promise<IGraphicStorage> {
const lineStore = useLineStore();
const mapId = lineStore.mapId;
const simulationId = lineStore.simulationId;
if (!mapId || !simulationId) {
throw new Error('获取数据异常未获取到地图ID或仿真ID');
}
const { proto: base64 } = await getPublishMapInfoByLineId(mapId + '');
if (base64) {
const storage =
relayCabinetGraphicData.RelayCabinetGraphicStorage.deserialize(
toUint8Array(base64)
);
const datas: GraphicData[] = [];
storage.relayCabinets.forEach((relayCabinet) => {
datas.push(new RelayCabinetData(relayCabinet));
});
storage.relays.forEach((relay) => {
datas.push(new RelayData(relay));
});
return Promise.resolve({
canvasProperty: storage.canvas,
datas: datas,
});
} else {
return Promise.resolve({
datas: [],
});
}
}

View File

@ -523,8 +523,12 @@ export class JlDrawApp extends GraphicApp implements IDrawApp {
*/
bindFormData(form: GraphicData): void {
this.formData = form;
if (this.selectedGraphics.length == 1) {
this.formData.copyFrom(this.selectedGraphics[0].saveData());
if (this.formData && this.selectedGraphics.length == 1) {
if (this.formData.graphicType == this.selectedGraphics[0].type) {
this.formData.copyFrom(this.selectedGraphics[0].saveData());
} else {
this.formData = undefined;
}
}
}

View File

@ -4,11 +4,7 @@ import {
FederatedPointerEvent,
Point,
} from 'pixi.js';
import {
IGraphicApp,
IGraphicAppConfig,
IGraphicScene,
} from '../app/JlGraphicApp';
import { IGraphicAppConfig, IGraphicScene } from '../app/JlGraphicApp';
import { JlGraphic } from '../core/JlGraphic';
export enum InteractionPluginType {
@ -417,10 +413,10 @@ export abstract class GraphicInteractionPlugin<G extends JlGraphic>
implements InteractionPlugin
{
readonly _type = InteractionPluginType.Graphic;
app: IGraphicApp;
app: IGraphicScene;
name: string; // 唯一标识
_pause: boolean;
constructor(name: string, app: IGraphicApp) {
constructor(name: string, app: IGraphicScene) {
this.app = app;
this.name = name;
this._pause = true;

View File

@ -2,7 +2,22 @@
<q-layout view="hHh LpR fFf">
<q-header reveal class="bg-primary text-white">
<q-toolbar>
<q-toolbar-title> {{ mapName }} </q-toolbar-title>
<q-btn-dropdown color="info" label="切换场景">
<q-list>
<q-item
v-for="(item, index) in projectInfo.mapInfoLinks"
:key="index"
clickable
v-close-popup
@click="switchScene(item)"
>
<q-item-section>
<q-item-label>{{ item.name }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<q-toolbar-title> {{ projectName }} </q-toolbar-title>
<q-btn
color="info"
label="销毁仿真"
@ -31,14 +46,18 @@
</template>
<script setup lang="ts">
import { onMounted, ref, computed, onUnmounted, watch } from 'vue';
import { onMounted, ref, computed, onUnmounted, watch, reactive } from 'vue';
import { useLineStore } from 'src/stores/line-store';
import { useRoute, useRouter } from 'vue-router';
import { destroySimulation } from 'src/api/Simulation';
import StateProperties from 'src/components/line-app/StateProperties.vue';
import LayerControlDialog from 'src/components/draw-app/dialogs/LayerControlDialog.vue';
import { layerList } from 'src/drawApp/lineApp';
import { useQuasar } from 'quasar';
import { LinkInfo, MapInfo, getProjectLinkInfo } from 'src/api/ProjectLinkApi';
import { ApiError } from 'src/boot/axios';
import { layerList } from 'src/drawApp/lineScene';
import { IGraphicScene } from 'src/jl-graphic';
import { SceneToPictureType } from 'src/drawApp/lineApp';
const $q = useQuasar();
const canvasWidth = ref(0);
@ -47,10 +66,13 @@ const headerHeight = ref(0);
const route = useRoute();
const router = useRouter();
const lineStore = useLineStore();
let simulationId = '';
const simulationId = (route.query.simulationId as string) || '';
const projectId = (route.query.projectId as string) || '';
const mapId = (route.query.mapId as string) || '';
let sceneName = '';
const drawerRight = ref(false);
const mapName = computed(() => lineStore.lineName);
const projectName = computed(() => projectInfo.name);
function onResize() {
const clientWidth = document.documentElement.clientWidth;
@ -73,17 +95,41 @@ function backConfirm() {
router.go(-1);
}
onMounted(() => {
const lineApp = lineStore.initLineApp();
let scene: null | IGraphicScene = null;
onMounted(async () => {
const dom = document.getElementById('line-app-container');
if (dom) {
simulationId = route.query.simulationId as string;
if (dom && mapId && simulationId) {
lineStore.setMapId(+mapId);
lineStore.setSimulationId(simulationId);
const lineApp = lineStore.initLineApp();
lineApp.bindDom(dom);
lineApp.reload();
try {
if (projectId) {
const res = await getProjectLinkInfo(+projectId);
projectInfo.name = res.name;
projectInfo.pid = res.pid + '';
projectInfo.mapInfoLinks = res.mapInfoLinks;
projectInfo.trainSizeLinks = res.trainSizeLinks;
const find = projectInfo.mapInfoLinks?.find((item) => {
return item.id == lineStore.mapId;
});
if (find) {
sceneName = getSceneName(find);
}
}
} catch (e) {
const error = e as ApiError;
$q.notify({
type: 'negative',
message: error.title,
});
}
scene = lineApp.getScene(sceneName);
scene.bindDom(dom);
scene.reload();
onResize();
} else {
lineStore.setLineId(null);
lineStore.setMapId(null);
lineStore.setSimulationId(null);
}
drawerRight.value = false;
@ -119,7 +165,7 @@ watch(
showDialog: val,
layerList: layerList,
showLayer: lineStore.showLayer,
app: lineStore.getLineApp(),
app: scene,
},
})
.onCancel(() => {
@ -134,4 +180,39 @@ function destroySimAndBack() {
}
backConfirm();
}
function switchScene(val: MapInfo) {
if (val.id == lineStore.mapId) return;
scene && scene.unbindDom();
lineStore.setMapId(val.id);
sceneName = getSceneName(val);
scene = lineApp.getScene(sceneName);
const dom = document.getElementById('line-app-container');
if (dom) {
scene.bindDom(dom);
scene.reload();
}
}
interface LinkParams extends Omit<LinkInfo, 'pid' | 'code'> {
name: string;
pid: string;
}
const projectInfo = reactive<LinkParams>({
name: '',
pid: '',
mapInfoLinks: [],
trainSizeLinks: [],
});
function getSceneName(val: MapInfo) {
const typeArr = [
SceneToPictureType.lineScene,
SceneToPictureType.pslScene,
SceneToPictureType.relayScene,
];
let name = typeArr[val.type] || SceneToPictureType.lineScene;
return name;
}
</script>

View File

@ -98,7 +98,6 @@ import {
destroySimulation,
getSimulationChannelName,
} from 'src/api/Simulation';
import { useLineStore } from 'src/stores/line-store';
import { useRouter } from 'vue-router';
import { PublishItem, getPublishList } from 'src/api/PublishApi';
import { getWebsocketUrl } from 'src/configs/UrlManage';
@ -108,7 +107,6 @@ import { CentrifugeMessagingClient } from 'src/jl-graphic/message/CentrifugeBrok
const router = useRouter();
const $q = useQuasar();
const lineStore = useLineStore();
const props = withDefaults(
defineProps<{
@ -207,12 +205,7 @@ async function startSimulationByProject(projectId: number) {
projectId: projectId,
};
const res = await createSimulationByProject(params);
const query = {
mapId: res.mapId,
simulationId: res.simulationId,
};
lineStore.setSimulationId(res.simulationId);
router.push({ path: '/linemap', query });
joinTest(res);
} catch (err) {
const error = err as ApiError;
$q.notify({
@ -266,8 +259,8 @@ function joinTest(val: SimulationIem) {
const query = {
mapId: val.mapId,
simulationId: val.simulationId,
projectId: val.projectId,
};
lineStore.setSimulationId(val.simulationId);
router.push({ path: '/linemap', query });
}
function endTest(val: SimulationIem) {

View File

@ -10,7 +10,13 @@ import {
getJkDrawApp,
initJkDrawApp,
} from 'src/drawApp/jkApp';
import { DrawAssistant, IDrawApp, IJlCanvas, JlGraphic } from 'src/jl-graphic';
import {
DrawAssistant,
GraphicData,
IDrawApp,
IJlCanvas,
JlGraphic,
} from 'src/jl-graphic';
import { markRaw } from 'vue';
export const useDrawStore = defineStore('draw', {
@ -80,6 +86,14 @@ export const useDrawStore = defineStore('draw', {
getJlCanvas(): IJlCanvas {
return this.getDrawApp().canvas;
},
bindFormData(form: GraphicData): void {
const app = this.getDrawApp();
app.bindFormData(form);
},
unbindFormData(form: GraphicData): void {
const app = this.getDrawApp();
app.unbindFormData(form);
},
initDrawApp() {
let app: IDrawApp | null = null;
switch (this.categoryType) {

View File

@ -17,6 +17,7 @@ export const useLineStore = defineStore('line', {
stateProCount: 0,
showLayer: [] as string[], // 显示的图层(草稿和发布图公用)
showLayerDialog: false, // 显示图层控制弹窗(草稿和发布图公用)
mapId: null as number | null,
}),
getters: {
selectedGraphicType: (state) => {
@ -71,5 +72,8 @@ export const useLineStore = defineStore('line', {
setShowLayerDialog(v: boolean) {
this.showLayerDialog = v;
},
setMapId(id: number | null) {
this.mapId = id;
},
},
});