生成计轴配置

This commit is contained in:
joylink_zhaoerwei 2024-10-30 11:45:19 +08:00
parent 9c7af7e256
commit fb6c01dbfd
7 changed files with 614 additions and 88 deletions

View File

@ -0,0 +1,186 @@
<template>
<q-list bordered separator class="rounded-borders">
<q-expansion-item
bordered
expand-separator
v-for="(configItem, index) in selectConfig"
:key="configItem"
v-model="configItem.expanded"
:label="configItem.code"
@click="toggleItem(index)"
>
<q-card>
<q-item no-wrap class="q-gutter-y-sm column">
<q-input
v-if="props.ableAdd"
outlined
v-model="configItem.code"
label="配置项类型"
lazy-rules
/>
<div class="q-gutter-sm row">
<q-chip
v-for="(item, selectIndex) in configItem.refDevicesCode"
:key="item"
square
color="primary"
text-color="white"
removable
@remove="removeSelect(selectIndex)"
clickable
@click="clickSelectCenter(selectIndex)"
>
{{ item }}
</q-chip>
</div>
<div>
<q-btn
v-show="configItem.refDevicesCode.length > 0"
style="width: 100px"
label="清空选择"
color="red"
class="q-mr-md"
@click="clearAllSelect(index)"
/>
<q-btn
v-if="props.ableAdd"
label="删除配置项"
color="secondary"
@click="deleteSelectConfig(index)"
/>
</div>
</q-item>
</q-card>
</q-expansion-item>
</q-list>
<q-btn
v-if="props.ableAdd"
class="q-mt-md"
label="增加配置项"
color="secondary"
@click="addSelectConfig"
/>
</template>
<script setup lang="ts">
import { inject, ref, watch } from 'vue';
import { IDrawApp, JlGraphic } from 'jl-graphic';
const props = withDefaults(
defineProps<{
drawStore: {
selectedGraphics: JlGraphic[];
getDrawApp(): IDrawApp;
};
ableAdd?: boolean;
}>(),
{ ableAdd: false }
);
const selectConfig = ref<
{
code: string;
refDevices: number[];
refDevicesCode: string[];
expanded: boolean;
}[]
>([
{
code: '配置项模版',
refDevices: [],
refDevicesCode: [],
expanded: false,
},
]);
let selectGraphic: JlGraphic[] = [];
defineExpose({
selectConfig,
selectGraphic,
});
interface GraphicData {
datas: { code: string };
}
const filterSelect = inject('filter') as (g: JlGraphic) => boolean;
watch(
() => props.drawStore.selectedGraphics,
(val) => {
if (val && val.length > 0 && clickIndex !== null) {
const selectFilter = props.drawStore.selectedGraphics?.filter(
filterSelect
) as JlGraphic[];
selectGraphic.push(...selectFilter);
selectGraphic = Array.from(new Set(selectGraphic));
props.drawStore.getDrawApp().updateSelected(...selectGraphic);
selectConfig.value[clickIndex].refDevicesCode = selectGraphic.map((g) =>
(g as JlGraphic & GraphicData).datas.code == ''
? g.id + ''
: (g as JlGraphic & GraphicData).datas.code
);
selectConfig.value[clickIndex].refDevices = selectGraphic.map(
(g) => g.id
) as number[];
}
}
);
let clickIndex: null | number = null;
function toggleItem(index: number) {
const drawApp = props.drawStore.getDrawApp();
selectGraphic = [];
drawApp.updateSelected();
if (selectConfig.value[index].expanded == true) {
clickIndex = index;
const select: JlGraphic[] = [];
selectConfig.value[index].refDevices.forEach((id: number) => {
const g = drawApp.queryStore.queryById(id);
select.push(g);
});
drawApp.updateSelected(...select);
} else {
clickIndex = null;
}
}
function removeSelect(removeIndex: number) {
const clickTarget = selectConfig.value[clickIndex as number];
selectGraphic.splice(removeIndex, 1);
clickTarget.refDevicesCode.splice(removeIndex, 1);
clickTarget.refDevices.splice(removeIndex, 1);
props.drawStore.getDrawApp().updateSelected(...selectGraphic);
}
function clickSelectCenter(index: number) {
const drawApp = props.drawStore.getDrawApp();
const clickTarget = selectConfig.value[clickIndex as number];
const clickGraphic = drawApp.queryStore.queryById(
clickTarget.refDevices[index]
);
drawApp.makeGraphicCenterShow(clickGraphic);
}
function clearAllSelect(index: number) {
selectConfig.value[index].refDevices = [];
selectConfig.value[index].refDevicesCode = [];
selectGraphic = [];
props.drawStore.getDrawApp().updateSelected();
}
function addSelectConfig() {
selectConfig.value.push({
code: '配置项模版',
refDevices: [],
refDevicesCode: [],
expanded: false,
});
}
function deleteSelectConfig(index: number) {
selectConfig.value.splice(index, 1);
selectGraphic = [];
props.drawStore.getDrawApp().updateSelected();
}
</script>

View File

@ -0,0 +1,183 @@
<template>
<q-card class="q-gutter-sm q-pa-sm">
<q-card-section>
<div class="text-h6">一键生成计轴配置</div>
</q-card-section>
<q-form ref="myForm">
<selectConfig-utils ref="selectConfigUtils" :drawStore="drawStore" />
<div class="q-mt-md q-gutter-md">
<q-btn label="确认修改" color="primary" @click="onSubmit" />
<q-btn label="返回" color="red" @click="goBack" />
<q-btn label="生成计轴" color="primary" @click="generateAxleCounting" />
</div>
<div class="q-mt-md q-gutter-md">
<q-btn
label="检查计轴"
color="primary"
@click="showErrorAxleCounting"
/>
<q-btn
v-if="showCheck"
label="上一个"
color="primary"
@click="clickSelectCenter(-1)"
/>
<q-btn
v-if="showCheck"
label="下一个"
color="primary"
@click="clickSelectCenter(1)"
/>
</div>
</q-form>
</q-card>
</template>
<script setup lang="ts">
import { onMounted, ref, provide } from 'vue';
import { QForm, useQuasar } from 'quasar';
import { JlGraphic } from 'jl-graphic';
import { useDrawStore } from 'src/stores/draw-store';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { Turnout } from 'src/graphics/turnout/Turnout';
import {
loadGenerateAxleCountingConfig,
setGenerateAxleCountingConfig,
} from 'src/drawApp';
import SelectConfigUtils from 'src/components/common/SelectConfigUtils.vue';
import { OneClickGenerate } from 'src/graphics/trainWindow/oneClickDrawAssistant';
import { AxleCounting } from 'src/graphics/axleCounting/AxleCounting';
//使
const filterSelect = (g: JlGraphic) => g instanceof Turnout;
const selectConfigUtils = ref<InstanceType<typeof SelectConfigUtils> | null>(
null
);
provide('filter', filterSelect);
const emit = defineEmits(['close']);
const drawStore = useDrawStore();
const $q = useQuasar();
onMounted(() => {
selectConfigUtils.value.selectConfig = [
{
code: 'bb连接的道岔',
refDevices: [],
refDevicesCode: [],
expanded: false,
},
{
code: '不生成计轴的道岔组',
refDevices: [],
refDevicesCode: [],
expanded: false,
},
];
const generateAxleCountingConfig = loadGenerateAxleCountingConfig();
if (generateAxleCountingConfig !== undefined) {
selectConfigUtils.value.selectConfig.forEach(
(generate: {
code: string;
refDevices: number[];
refDevicesCode: string[];
}) => {
if (generate.code == 'bb连接的道岔') {
generate.refDevices = generateAxleCountingConfig.bbConnect;
generateAxleCountingConfig.bbConnect.forEach((id) => {
const g = drawStore.getDrawApp().queryStore.queryById(id);
generate.refDevicesCode.push(g.code);
});
} else if (generate.code == '不生成计轴的道岔组') {
generate.refDevices = generateAxleCountingConfig.noGenerateGroup;
generateAxleCountingConfig.noGenerateGroup.forEach((id) => {
const g = drawStore.getDrawApp().queryStore.queryById(id);
generate.refDevicesCode.push(g.code);
});
}
}
);
}
});
const myForm = ref<QForm | null>(null);
async function onSubmit() {
myForm.value?.validate().then(async (res) => {
if (res) {
try {
const generateAxleCountingConfig =
new graphicData.GenerateAxleCountingConfig();
selectConfigUtils.value.selectConfig.forEach(
(generate: { code: string; refDevices: number[] }) => {
if (generate.code == 'bb连接的道岔') {
generateAxleCountingConfig.bbConnect = generate.refDevices;
} else if (generate.code == '不生成计轴的道岔组') {
generateAxleCountingConfig.noGenerateGroup = generate.refDevices;
}
}
);
setGenerateAxleCountingConfig(generateAxleCountingConfig);
$q.notify({
type: 'positive',
message: '更新成功',
});
} catch (err) {
$q.notify({
type: 'negative',
message: '更新失败',
});
}
}
});
}
function goBack() {
emit('close');
}
function generateAxleCounting() {
drawStore.oneClickType = 'AxleCounting';
drawStore.getDrawApp().interactionPlugin(OneClickGenerate.Type).resume();
}
const selectConfig = ref<
{
axleCountingId: number;
axleCountingCode: string;
}[]
>([]);
function showErrorAxleCounting() {
showCheck.value = true;
const axleCountings = drawStore
.getDrawApp()
.queryStore.queryByType<AxleCounting>(AxleCounting.Type);
const erroeAxleCountings = axleCountings
.filter((g) => g.datas.axleCountingRef.length < 2)
.sort((a, b) => a.position.x - b.position.x);
erroeAxleCountings.forEach((axleCounting) => {
selectConfig.value.push({
axleCountingId: axleCounting.id,
axleCountingCode: axleCounting.datas.code,
});
});
}
const currentIndex = ref(-1);
const showCheck = ref(false);
function clickSelectCenter(add: number) {
if (
currentIndex.value + add < 0 ||
currentIndex.value + add >= selectConfig.value.length
)
return;
currentIndex.value = currentIndex.value + add;
const target = drawStore
.getDrawApp()
.queryStore.queryById(
selectConfig.value[currentIndex.value].axleCountingId
);
drawStore.getDrawApp().makeGraphicCenterShow(target);
drawStore.getDrawApp().updateSelected(target);
}
</script>

View File

@ -289,6 +289,9 @@ export function initDrawApp(): IDrawApp {
if (app.drawing) return;
handleRIghtClick(e);
});
app.on('destroy', () => {
generateAxleCountingConfig = new graphicData.GenerateAxleCountingConfig();
});
app.addKeyboardListener(
new KeyListener({
value: 'KeyS',
@ -557,6 +560,7 @@ export function saveDrawDatas(app: IDrawApp) {
// item.pcRef.nid = +item.pcRef.id;
// }
// });
storage.generateAxleCountingConfig = generateAxleCountingConfig;
const base64 = fromUint8Array(storage.serialize());
console.log('保存数据', storage);
// localStorage.setItem(StorageKey, base64);
@ -579,6 +583,7 @@ export async function loadDrawDatas(): Promise<IGraphicStorage> {
);
console.log('加载数据', storage);
const datas: GraphicData[] = [];
generateAxleCountingConfig = storage.generateAxleCountingConfig;
storage.links.forEach((link) => {
datas.push(new LinkData(link));
});
@ -642,3 +647,15 @@ export async function loadDrawDatas(): Promise<IGraphicStorage> {
datas: [],
});
}
//一键生成计轴配置
let generateAxleCountingConfig = new graphicData.GenerateAxleCountingConfig();
export function loadGenerateAxleCountingConfig() {
return generateAxleCountingConfig;
}
export function setGenerateAxleCountingConfig(
newScreenDoorConfig: graphicData.GenerateAxleCountingConfig
) {
generateAxleCountingConfig = newScreenDoorConfig;
}

View File

@ -20,6 +20,7 @@ import { Turnout, TurnoutPort } from '../turnout/Turnout';
import { IRelatedRefData, createRelatedRefProto } from '../CommonGraphics';
import { Signal } from '../signal/Signal';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { loadGenerateAxleCountingConfig } from 'src/drawApp';
export interface IAxleCountingDrawOptions {
newData: () => IAxleCountingData;
@ -80,6 +81,21 @@ export class AxleCountingDraw extends GraphicDrawAssistant<
refGraphic: Section | Turnout,
refPort: TurnoutPort | SectionPort
) {
const generateAxleCountingConfig = loadGenerateAxleCountingConfig();
if (generateAxleCountingConfig?.noGenerateGroup !== undefined) {
const noGenerateGroup = generateAxleCountingConfig.noGenerateGroup;
for (let i = 0; i < noGenerateGroup.length; i++) {
if (
noGenerateGroup[i] == graphic.id &&
((i % 2 == 0 && refGraphic.id == noGenerateGroup[i + 1]) ||
(i % 2 == 1 && refGraphic.id == noGenerateGroup[i - 1]))
) {
map.set(`${graphic.id}-${port}`, 1);
map.set(`${refGraphic.id}-${refPort}`, 1);
return;
}
}
}
if (
graphic.type == 'Turnout' &&
reftype == 'Turnout' &&

View File

@ -122,8 +122,11 @@
<q-drawer show-if-above bordered v-model="rightDrawerOpen" side="right">
<q-resize-observer @resize="onRightResize" />
<!-- drawer content -->
<draw-properties></draw-properties>
<axleCounting-config
v-if="showGenerateAxleCountingConfig"
@close="closeGenerateAxleCountingConfig"
/>
<draw-properties v-else></draw-properties>
</q-drawer>
<q-page-container>
@ -189,6 +192,7 @@ import {
findContainDevice,
handleCentralizedStationsData,
} from 'src/graphics/concentrationDividingLine/ConcentrationDividingLineUtils';
import AxleCountingConfig from 'src/components/draw-app/properties/AxleCountingConfig.vue';
const route = useRoute();
const router = useRouter();
@ -358,10 +362,14 @@ function oneClickSeparator() {
.getDrawAssistant(Separator.Type) as SeparatorDraw;
separatorDraw.oneGenerates();
}
const showGenerateAxleCountingConfig = ref(false);
const closeGenerateAxleCountingConfig = () => {
showGenerateAxleCountingConfig.value = false;
};
function oneClickAxleCounting() {
//
drawStore.oneClickType = 'AxleCounting';
drawStore.getDrawApp().interactionPlugin(OneClickGenerate.Type).resume();
showGenerateAxleCountingConfig.value = true;
}
function oneClickTurnoutSection() {

View File

@ -28,6 +28,7 @@ export namespace graphicData {
separators?: Separator[];
logicSections?: LogicSection[];
concentrationDividingLines?: ConcentrationDividingLine[];
generateAxleCountingConfig?: GenerateAxleCountingConfig;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], this.#one_of_decls);
@ -92,6 +93,9 @@ export namespace graphicData {
if ("concentrationDividingLines" in data && data.concentrationDividingLines != undefined) {
this.concentrationDividingLines = data.concentrationDividingLines;
}
if ("generateAxleCountingConfig" in data && data.generateAxleCountingConfig != undefined) {
this.generateAxleCountingConfig = data.generateAxleCountingConfig;
}
}
}
get canvas() {
@ -217,6 +221,15 @@ export namespace graphicData {
set concentrationDividingLines(value: ConcentrationDividingLine[]) {
pb_1.Message.setRepeatedWrapperField(this, 20, value);
}
get generateAxleCountingConfig() {
return pb_1.Message.getWrapperField(this, GenerateAxleCountingConfig, 21) as GenerateAxleCountingConfig;
}
set generateAxleCountingConfig(value: GenerateAxleCountingConfig) {
pb_1.Message.setWrapperField(this, 21, value);
}
get has_generateAxleCountingConfig() {
return pb_1.Message.getField(this, 21) != null;
}
static fromObject(data: {
canvas?: ReturnType<typeof Canvas.prototype.toObject>;
links?: ReturnType<typeof Link.prototype.toObject>[];
@ -238,6 +251,7 @@ export namespace graphicData {
separators?: ReturnType<typeof Separator.prototype.toObject>[];
logicSections?: ReturnType<typeof LogicSection.prototype.toObject>[];
concentrationDividingLines?: ReturnType<typeof ConcentrationDividingLine.prototype.toObject>[];
generateAxleCountingConfig?: ReturnType<typeof GenerateAxleCountingConfig.prototype.toObject>;
}): RtssGraphicStorage {
const message = new RtssGraphicStorage({});
if (data.canvas != null) {
@ -300,6 +314,9 @@ export namespace graphicData {
if (data.concentrationDividingLines != null) {
message.concentrationDividingLines = data.concentrationDividingLines.map(item => ConcentrationDividingLine.fromObject(item));
}
if (data.generateAxleCountingConfig != null) {
message.generateAxleCountingConfig = GenerateAxleCountingConfig.fromObject(data.generateAxleCountingConfig);
}
return message;
}
toObject() {
@ -324,6 +341,7 @@ export namespace graphicData {
separators?: ReturnType<typeof Separator.prototype.toObject>[];
logicSections?: ReturnType<typeof LogicSection.prototype.toObject>[];
concentrationDividingLines?: ReturnType<typeof ConcentrationDividingLine.prototype.toObject>[];
generateAxleCountingConfig?: ReturnType<typeof GenerateAxleCountingConfig.prototype.toObject>;
} = {};
if (this.canvas != null) {
data.canvas = this.canvas.toObject();
@ -385,6 +403,9 @@ export namespace graphicData {
if (this.concentrationDividingLines != null) {
data.concentrationDividingLines = this.concentrationDividingLines.map((item: ConcentrationDividingLine) => item.toObject());
}
if (this.generateAxleCountingConfig != null) {
data.generateAxleCountingConfig = this.generateAxleCountingConfig.toObject();
}
return data;
}
serialize(): Uint8Array;
@ -431,6 +452,8 @@ export namespace graphicData {
writer.writeRepeatedMessage(19, this.logicSections, (item: LogicSection) => item.serialize(writer));
if (this.concentrationDividingLines.length)
writer.writeRepeatedMessage(20, this.concentrationDividingLines, (item: ConcentrationDividingLine) => item.serialize(writer));
if (this.has_generateAxleCountingConfig)
writer.writeMessage(21, this.generateAxleCountingConfig, () => this.generateAxleCountingConfig.serialize(writer));
if (!w)
return writer.getResultBuffer();
}
@ -500,6 +523,9 @@ export namespace graphicData {
case 20:
reader.readMessage(message.concentrationDividingLines, () => pb_1.Message.addToRepeatedWrapperField(message, 20, ConcentrationDividingLine.deserialize(reader), ConcentrationDividingLine));
break;
case 21:
reader.readMessage(message.generateAxleCountingConfig, () => message.generateAxleCountingConfig = GenerateAxleCountingConfig.deserialize(reader));
break;
default: reader.skipField();
}
}
@ -5241,4 +5267,94 @@ export namespace graphicData {
return Separator.deserialize(bytes);
}
}
export class GenerateAxleCountingConfig extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
bbConnect?: number[];
noGenerateGroup?: number[];
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [1, 2], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("bbConnect" in data && data.bbConnect != undefined) {
this.bbConnect = data.bbConnect;
}
if ("noGenerateGroup" in data && data.noGenerateGroup != undefined) {
this.noGenerateGroup = data.noGenerateGroup;
}
}
}
get bbConnect() {
return pb_1.Message.getFieldWithDefault(this, 1, []) as number[];
}
set bbConnect(value: number[]) {
pb_1.Message.setField(this, 1, value);
}
get noGenerateGroup() {
return pb_1.Message.getFieldWithDefault(this, 2, []) as number[];
}
set noGenerateGroup(value: number[]) {
pb_1.Message.setField(this, 2, value);
}
static fromObject(data: {
bbConnect?: number[];
noGenerateGroup?: number[];
}): GenerateAxleCountingConfig {
const message = new GenerateAxleCountingConfig({});
if (data.bbConnect != null) {
message.bbConnect = data.bbConnect;
}
if (data.noGenerateGroup != null) {
message.noGenerateGroup = data.noGenerateGroup;
}
return message;
}
toObject() {
const data: {
bbConnect?: number[];
noGenerateGroup?: number[];
} = {};
if (this.bbConnect != null) {
data.bbConnect = this.bbConnect;
}
if (this.noGenerateGroup != null) {
data.noGenerateGroup = this.noGenerateGroup;
}
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.bbConnect.length)
writer.writePackedUint32(1, this.bbConnect);
if (this.noGenerateGroup.length)
writer.writePackedUint32(2, this.noGenerateGroup);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): GenerateAxleCountingConfig {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new GenerateAxleCountingConfig();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
message.bbConnect = reader.readPackedUint32();
break;
case 2:
message.noGenerateGroup = reader.readPackedUint32();
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): GenerateAxleCountingConfig {
return GenerateAxleCountingConfig.deserialize(bytes);
}
}
}

@ -1 +1 @@
Subproject commit 4f9012b0795f62bf352b078ebbc1b1fffa86849d
Subproject commit 91cfbc3ee5574419615ae177661239cdc0d7d53e