范围管理拆分App

This commit is contained in:
Yuan 2023-08-25 17:27:25 +08:00
parent 1b0582979f
commit b5795f19e0
9 changed files with 278 additions and 35 deletions

View File

@ -1,5 +1,5 @@
<template>
<div v-if="lineStore.selectedGraphics !== null">
<div v-if="rangeConfigStore.selectedGraphics !== null">
<q-card class="q-gutter-sm q-pa-sm">
<q-card-section>
<div class="text-h6">{{ handleState }}</div>
@ -66,7 +66,7 @@
</template>
<script setup lang="ts">
import { useLineStore } from 'src/stores/line-store';
// import { useLineStore } from 'src/stores/line-store';
import { reactive, ref, watch } from 'vue';
import { LogicSection } from 'src/graphics/logicSection/LogicSection';
import { Turnout } from 'src/graphics/turnout/Turnout';
@ -80,13 +80,15 @@ import {
queryDeviceRangeById,
} from 'src/api/ConfigApi';
import { JlGraphic } from 'src/jl-graphic';
import { saveAlertTypeData, showAlertTypeData } from './alarm/alarmInfoEnum';
import { saveAlertTypeData, showAlertTypeData } from '../alarm/alarmInfoEnum';
import { Section, SectionType } from 'src/graphics/section/Section';
import { useRangeConfigStore } from 'src/stores/range-config-store';
import { getRangeConfigApp } from 'src/drawApp/rangeConfigApp';
defineExpose({ searchById });
const route = useRoute();
const lineStore = useLineStore();
const rangeConfigStore = useRangeConfigStore();
const $q = useQuasar();
const rangeConfig = reactive<{
areaName: string;
@ -141,10 +143,10 @@ enum DeviceTypeShow {
let selectGraphic: JlGraphic[] = [];
watch(
() => lineStore.selectedGraphics,
() => rangeConfigStore.selectedGraphics,
(val) => {
if (val && val.length > 0) {
const deviceFilter = lineStore.selectedGraphics?.filter(
const deviceFilter = rangeConfigStore.selectedGraphics?.filter(
(g) =>
g.type == rangeConfig.deviceType ||
(g.type == Section.Type &&
@ -153,7 +155,7 @@ watch(
) as JlGraphic[];
selectGraphic.push(...deviceFilter);
selectGraphic = Array.from(new Set(selectGraphic));
lineStore.getLineApp().updateSelected(...selectGraphic);
getRangeConfigApp().updateSelected(...selectGraphic);
device.value = selectGraphic.map((g) => g.code) as string[];
rangeConfig.device = selectGraphic.map((g) => g.id) as string[];
}
@ -219,11 +221,11 @@ async function searchById(id: number) {
);
const select: JlGraphic[] = [];
response.data.data.forEach((id: string) => {
const g = lineStore.getLineApp().queryStore.queryById(id);
const g = getRangeConfigApp().queryStore.queryById(id);
select.push(g);
device.value.push(g.code);
});
lineStore.getLineApp().updateSelected(...select);
getRangeConfigApp().updateSelected(...select);
} catch (err) {
$q.notify({
type: 'negative',
@ -237,13 +239,13 @@ function removeSelect(code: string) {
selectGraphic.splice(removeIndex, 1);
device.value.splice(removeIndex, 1);
rangeConfig.device.splice(removeIndex, 1);
lineStore.getLineApp().updateSelected(...selectGraphic);
getRangeConfigApp().updateSelected(...selectGraphic);
}
function clearSelect() {
device.value = [];
selectGraphic = [];
lineStore.getLineApp().updateSelected();
getRangeConfigApp().updateSelected();
}
function onReset() {

View File

@ -6,7 +6,7 @@ import {
} from 'src/api/ConfigApi';
import { ref } from 'vue';
import { useRoute } from 'vue-router';
import DraggableDialog from './common/DraggableDialog.vue';
import DraggableDialog from '../common/DraggableDialog.vue';
import { QTable, useQuasar } from 'quasar';
import { errorNotify } from 'src/utils/CommonNotify';
import { deviceTypeMap } from 'src/api/TrainApi';

View File

@ -0,0 +1,139 @@
import {
LogicSection,
LogicSectionTemplate,
} from 'src/graphics/logicSection/LogicSection';
import { Platform, PlatformTemplate } from 'src/graphics/platform/Platform';
import { SectionTemplate } from 'src/graphics/section/Section';
import { Signal, SignalTemplate } from 'src/graphics/signal/Signal';
import { Station, StationTemplate } from 'src/graphics/station/Station';
import { Train, TrainTemplate } from 'src/graphics/train/Train';
import { Turnout, TurnoutTemplate } from 'src/graphics/turnout/Turnout';
import { GraphicApp, GraphicData } from 'src/jl-graphic';
import {
LogicSectionData,
LogicSectionState,
} from './graphics/LogicSectionInteraction';
import { SeparatorTemplate } from 'src/graphics/separator/Separator';
import { AxleCountingTemplate } from 'src/graphics/axleCounting/AxleCounting';
import { TrainWindowTemplate } from 'src/graphics/trainWindow/TrainWindow';
import { TrainData, TrainState } from './graphics/TrainInteraction';
import { SignalData, SignalState } from './graphics/SignalInteraction';
import { PlatformData, PlatformState } from './graphics/PlatformInteraction';
import { StationData, StationState } from './graphics/StationInteraction';
import { TurnoutData, TurnoutStates } from './graphics/TurnoutInteraction';
import { SectionData } from './graphics/SectionInteraction';
import { SeparatorData } from './graphics/SeparatorInteraction';
import { AxleCountingData } from './graphics/AxleCountingInteraction';
import { TrainWindowData } from './graphics/TrainWindowInteraction';
import { getPublishMapInfoByLineId } from 'src/api/PublishApi';
import { useRangeConfigStore } from 'src/stores/range-config-store';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { toUint8Array } from 'js-base64';
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
let rangeConfigApp: GraphicApp;
export function getRangeConfigApp() {
return rangeConfigApp;
}
export function initRangeConfigApp(dom: HTMLElement) {
rangeConfigApp = new GraphicApp(dom);
const graphicTemplate = [
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 LogicSectionTemplate(new LogicSectionData(), new LogicSectionState()),
new SeparatorTemplate(new SeparatorData()),
new AxleCountingTemplate(new AxleCountingData()),
new TrainWindowTemplate(new TrainWindowData()),
];
rangeConfigApp.registerGraphicTemplates(...graphicTemplate);
rangeConfigApp.setOptions({
mouseToolOptions: {
boxSelect: true,
viewportDrag: true,
wheelZoom: true,
boxSelectColor: '0xff0000',
},
interactiveTypeOptions: {
interactiveGraphicTypeIncludes: [
Signal.Type,
Platform.Type,
Station.Type,
Train.Type,
LogicSection.Type,
Turnout.Type,
],
},
});
return rangeConfigApp;
}
export async function loadLineDatas(app: GraphicApp) {
const store = useRangeConfigStore();
const lineId = store.lineId;
if (!lineId) return;
const { proto: base64, name: lineName } = await getPublishMapInfoByLineId(
lineId,
'line'
);
store.setLineName(lineName);
if (base64) {
const storage = graphicData.RtssGraphicStorage.deserialize(
toUint8Array(base64)
);
app.updateCanvas(storage.canvas);
const datas: GraphicData[] = [];
storage.Platforms.forEach((platform) => {
const g = new PlatformData(platform);
datas.push(g);
});
const quickJumpMenuItem: MenuItemOptions[] = [];
storage.stations.forEach((station) => {
datas.push(new StationData(station));
const item: MenuItemOptions = {
name: station.name,
handler: () => {
const g = app.queryStore.queryById(station.common.id);
if (g) {
app.makeGraphicCenterShow(g);
}
},
};
quickJumpMenuItem.push(item);
});
storage.turnouts.forEach((turnout) => {
datas.push(new TurnoutData(turnout));
});
storage.section.forEach((section) => {
datas.push(new SectionData(section));
});
storage.logicSections.forEach((section) => {
datas.push(new LogicSectionData(section));
});
storage.separators.forEach((separator) => {
datas.push(new SeparatorData(separator));
});
storage.axleCountings.forEach((axleCounting) => {
datas.push(new AxleCountingData(axleCounting));
});
await app.loadGraphic(datas);
const QuickJumpMenu = new ContextMenu({
name: '快捷跳转',
groups: [
{
items: quickJumpMenuItem,
},
],
});
app.registerMenu(QuickJumpMenu);
app.canvas.on('_rightclick', (e) => {
QuickJumpMenu.open(e.global);
});
}
}

View File

@ -112,6 +112,7 @@ enum statusTextColor {
const deviceTypeString = new Map();
deviceTypeString.set(state.DeviceType.TRACK, LogicSection.Type);
deviceTypeString.set(state.DeviceType.SWITCH_TRACK, Section.Type);
console.log(1);
export const trainConsts = {
codeWidth: 120,

View File

@ -3,9 +3,6 @@
<q-header reveal class="bg-primary text-white">
<q-toolbar>
<q-toolbar-title> {{ mapName }} </q-toolbar-title>
<q-btn class="q-mr-xl" color="primary" @click="openRangeList"
>范围列表</q-btn
>
<q-btn color="info" label="返回" @click="backConfirm" />
</q-toolbar>
<q-resize-observer @resize="onHeaderResize" />
@ -14,9 +11,6 @@
<q-page-container>
<div id="line-app-container"></div>
</q-page-container>
<q-drawer side="right" v-model="drawerRight" show-if-above bordered>
<range-config ref="rangeConfigEdit"></range-config>
</q-drawer>
</q-layout>
</template>
@ -27,10 +21,7 @@ import { useLineNetStore } from 'src/stores/line-net-store';
import { useRoute, useRouter } from 'vue-router';
import { loadLineDatas, getLineApp } from 'src/drawApp/lineApp';
import { loadLineNetDatas, getLineNetApp } from 'src/drawApp/lineNetApp';
import rangeConfig from 'src/components/rangeConfig.vue';
import RangeList from 'src/components/RangeList.vue';
import { useQuasar } from 'quasar';
import { IAreaConfigListItem } from 'src/api/ConfigApi';
const $q = useQuasar();
const canvasWidth = ref(0);
@ -41,8 +32,6 @@ const router = useRouter();
const mapType = ref(route.params.type as string);
const lineStore = useLineStore();
const lineNetStore = useLineNetStore();
const drawerRight = ref();
const rangeConfigEdit = ref<{ searchById: (id: number) => void } | null>(null);
const mapName = computed(() => lineStore.lineName || lineNetStore.lineNetName);
@ -94,15 +83,15 @@ onMounted(() => {
}
});
function openRangeList() {
const dialog = $q.dialog({
component: RangeList,
componentProps: {
onEditClick: (row: IAreaConfigListItem) => {
dialog.hide();
rangeConfigEdit.value?.searchById(row.id);
},
},
});
}
// function openRangeList() {
// const dialog = $q.dialog({
// component: RangeList,
// componentProps: {
// onEditClick: (row: IAreaConfigListItem) => {
// dialog.hide();
// rangeConfigEdit.value?.searchById(row.id);
// },
// },
// });
// }
</script>

View File

@ -0,0 +1,74 @@
<script setup lang="ts">
import { loadLineDatas } from 'src/drawApp/rangeConfigApp';
import { getRangeConfigApp } from 'src/drawApp/rangeConfigApp';
import { useRangeConfigStore } from 'src/stores/range-config-store';
import { computed, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import RangeConfig from 'src/components/rangeConfigApp/RangeConfig.vue';
import RangeList from 'src/components/rangeConfigApp/RangeList.vue';
import { IAreaConfigListItem } from 'src/api/ConfigApi';
import { useQuasar } from 'quasar';
const $q = useQuasar();
const rangeConfigStore = useRangeConfigStore();
const route = useRoute();
const mapName = computed(() => rangeConfigStore.lineName);
function onResize() {
const { clientWidth, clientHeight } = document.body;
const dom = document.getElementById('rangeConfigContainer');
if (dom) {
dom.style.width = clientWidth + 'px';
dom.style.height = clientHeight - 50 + 'px';
}
const app = getRangeConfigApp();
if (app) app.onDomResize(clientWidth, clientHeight);
}
const rangeConfigEdit = ref<InstanceType<typeof RangeConfig>>();
function openRangeList() {
const dialog = $q.dialog({
component: RangeList,
componentProps: {
onEditClick: (row: IAreaConfigListItem) => {
dialog.hide();
rangeConfigEdit.value?.searchById(row.id);
},
},
});
}
onMounted(() => {
const dom = document.querySelector<HTMLElement>('#rangeConfigContainer');
if (!dom) return;
rangeConfigStore.lineId = Number(route.params.id);
const rangeConfigApp = rangeConfigStore.initRangeConfigApp(dom);
loadLineDatas(rangeConfigApp);
});
const isRangeConfigDrawerOpen = ref(false);
</script>
<template>
<QLayout view="hHh LpR fFf">
<QHeader reveal class="bg-primary">
<QToolbar>
<QBtn icon="sym_o_arrow_back" flat @click="$router.go(-1)"></QBtn>
<QToolbarTitle>{{ mapName }}</QToolbarTitle>
<QBtn color="primary" @click="openRangeList">范围列表</QBtn>
</QToolbar>
</QHeader>
<QPageContainer>
<div id="rangeConfigContainer" />
</QPageContainer>
<QResizeObserver @resize="onResize" />
<QDrawer
side="right"
v-model="isRangeConfigDrawerOpen"
show-if-above
bordered
>
<RangeConfig ref="rangeConfigEdit"></RangeConfig>
</QDrawer>
</QLayout>
</template>

View File

@ -30,9 +30,15 @@
<q-btn
color="primary"
:disable="operateDisabled"
label="范围配置"
label="预览"
:to="`/linemap/${props.row.lineId}/${props.row.type}`"
/>
<q-btn
color="primary"
:disable="operateDisabled || props.row.type !== 'Line'"
label="范围配置"
:to="`/rangeConfig/${props.row.lineId}`"
></q-btn>
<q-btn
color="red"
:disable="operateDisabled"

View File

@ -77,6 +77,11 @@ const routes: RouteRecordRaw[] = [
name: 'linemap',
component: () => import('layouts/LineLayout.vue'),
},
{
path: '/rangeConfig/:id',
name: 'rangeConfig',
component: () => import('layouts/RangeConfigLayout.vue'),
},
// {
// path: '/line/monitor/:lineId',
// name: 'linemonitor',

View File

@ -0,0 +1,27 @@
import { defineStore } from 'pinia';
import { initRangeConfigApp } from 'src/drawApp/rangeConfigApp';
import { JlGraphic } from 'src/jl-graphic';
export const useRangeConfigStore = defineStore('rangeConfig', {
state: () => ({
lineName: '',
lineId: NaN,
selectedGraphics: [] as JlGraphic[],
}),
actions: {
initRangeConfigApp(dom: HTMLElement) {
const app = initRangeConfigApp(dom);
app.on('graphicselectedchange', () => {
this.selectedGraphics = app.selectedGraphics;
});
this.selectedGraphics = [];
return app;
},
setLineId(id: number) {
this.lineId = id;
},
setLineName(name: string) {
this.lineName = name;
},
},
});