diff --git a/src/api/AlertMock.ts b/src/api/AlertMock.ts index 3823b34..0f48670 100644 --- a/src/api/AlertMock.ts +++ b/src/api/AlertMock.ts @@ -9,9 +9,12 @@ export function mockLocalDemoTestSet( alertType: string, data: { lineId: number; - deviceInfos: { deviceName: string; deviceType: string }[]; - status: string; - groupId?: string; + deviceInfos: { + deviceName: string; + deviceType: string; + status: string; + groupId?: string; + }[]; } ) { return api.post(`${alertUriBase}/localDemoTest/${alertType}`, data); diff --git a/src/api/ConfigApi.ts b/src/api/ConfigApi.ts index 82aeb7f..02d144f 100644 --- a/src/api/ConfigApi.ts +++ b/src/api/ConfigApi.ts @@ -45,7 +45,7 @@ export interface IAreaConfigItem { areaName: string; deviceType: string; alertTypes: string[]; - data: string[]; + data: number[]; } export function deviceRangeSet(data: IAreaConfigItem) { return api.post('/api/config/device/area/save', data); diff --git a/src/components/alarm/setAlarmText.vue b/src/components/alarm/setAlarmText.vue index d0f3ae6..a805df6 100644 --- a/src/components/alarm/setAlarmText.vue +++ b/src/components/alarm/setAlarmText.vue @@ -25,52 +25,79 @@ v-model="setAlartTextData.alertType" :options="optionsAlertType" :rules="[(val) => val.length > 0 || '请选择故障类型!']" - /> - - - - - 框选的设备 -
- - {{ item.deviceName }} - -
- -
-
+ + + + + +
+ + {{ item.deviceName }} + +
+
+ + +
+
+
+
+
({ lineId: '', alertType: '', - deviceInfos: [], - status: '', - groupId: '', + groupList: [ + { + groupName: '测试组', + groupId: '', + status: '', + deviceInfos: [], + expanded: false, + }, + ], }); const optionsAlertType = [ '蓝显', @@ -141,7 +181,12 @@ let selectGraphic: JlGraphic[] = []; watch( () => lineStore.selectedGraphics, (val) => { - if (val && val.length > 0 && setAlartTextData.value.alertType) { + if ( + val && + val.length > 0 && + setAlartTextData.value.alertType && + clickIndex !== null + ) { const selectGraphicId = selectGraphic.map((g) => g.id); const appSelectedGraphicsId = lineStore.selectedGraphics?.map( (g) => g.id @@ -176,12 +221,14 @@ watch( } selectGraphic = Array.from(new Set(selectGraphic)); lineStore.getLineApp().updateSelected(...selectGraphic); - setAlartTextData.value.deviceInfos = []; + setAlartTextData.value.groupList[clickIndex].deviceInfos = []; selectGraphic.forEach((g) => { - setAlartTextData.value.deviceInfos.push({ - deviceName: g.code, - deviceType: (DeviceType as never)[g.type + ''], - }); + setAlartTextData.value.groupList[clickIndex as number].deviceInfos.push( + { + deviceName: g.code, + deviceType: (DeviceType as never)[g.type + ''], + } + ); }); } } @@ -196,7 +243,6 @@ onMounted(() => { wheelZoom: true, }, }); - clearSelect(); onReset(); setAlartTextData.value.lineId = lineStore.lineId as unknown as string; }); @@ -208,12 +254,25 @@ const $q = useQuasar(); async function onSubmit() { myForm.value?.validate().then(async (res) => { if (res) { + const deviceInfos = setAlartTextData.value.groupList + .map((group) => { + const deviceInfo = group.deviceInfos.map((deviceInfo) => { + const status = group.status; + const groupId = group.groupId || ''; + return { + deviceName: deviceInfo.deviceName, + deviceType: deviceInfo.deviceType, + status, + groupId, + }; + }); + return deviceInfo; + }) + .flat(); try { const params = { lineId: +setAlartTextData.value.lineId, - deviceInfos: setAlartTextData.value.deviceInfos, - status: setAlartTextData.value.status, - groupId: setAlartTextData.value.groupId, + deviceInfos, }; const alertType = (saveAlertTypeData as never)[ setAlartTextData.value.alertType + '' @@ -237,28 +296,101 @@ async function onSubmit() { }); } -function removeSelect(code: { deviceName: string; deviceType: string }) { - const removeIndex = setAlartTextData.value.deviceInfos.findIndex( - (item) => item == code - ); +let clickIndex: null | number = null; +function toggleItem(index: number) { + const lineApp = lineStore.getLineApp(); + selectGraphic = []; + lineApp.updateSelected(); + if (setAlartTextData.value.groupList[index].expanded == true) { + clickIndex = index; + const select: JlGraphic[] = []; + setAlartTextData.value.groupList[index].deviceInfos.forEach( + (deviceInfo) => { + const deviceType = ( + Object.keys(DeviceType) as Array + ).find((key) => DeviceType[key] === deviceInfo.deviceType) as string; + const g = lineApp.queryStore.queryByCodeAndType( + deviceInfo.deviceName, + deviceType + ) as JlGraphic; + select.push(g); + } + ); + lineApp.updateSelected(...select); + } else { + clickIndex = null; + } +} + +function clickSelectCenter(index: number) { + const lineApp = lineStore.getLineApp(); + const clickTarget = setAlartTextData.value.groupList[clickIndex as number]; + const deviceType = ( + Object.keys(DeviceType) as Array + ).find( + (key) => DeviceType[key] === clickTarget.deviceInfos[index].deviceType + ) as string; + const clickGraphic = lineApp.queryStore.queryByCodeAndType( + clickTarget.deviceInfos[index].deviceName, + deviceType + ) as JlGraphic; + lineApp.makeGraphicCenterShow(clickGraphic); +} + +function removeSelect(removeIndex: number) { + const clickTarget = setAlartTextData.value.groupList[clickIndex as number]; selectGraphic.splice(removeIndex, 1); - setAlartTextData.value.deviceInfos.splice(removeIndex, 1); + clickTarget.deviceInfos.splice(removeIndex, 1); lineStore.getLineApp().updateSelected(...selectGraphic); } -function clearSelect() { - setAlartTextData.value.deviceInfos = []; +function clearAllSelect(index: number) { + setAlartTextData.value.groupList[index].deviceInfos = []; selectGraphic = []; lineStore.getLineApp().updateSelected(); } +function addSelectConfig() { + setAlartTextData.value.groupList.push({ + groupName: '测试组', + groupId: '', + status: '', + deviceInfos: [], + expanded: false, + }); +} + +function deleteSelectConfig(index: number) { + setAlartTextData.value.groupList.splice(index, 1); + selectGraphic = []; + lineStore.getLineApp().updateSelected(); +} + +function onChooseAlertType() { + setAlartTextData.value.groupList = [ + { + groupName: '测试组', + groupId: '', + status: '', + deviceInfos: [], + expanded: false, + }, + ]; +} + function onReset() { setAlartTextData.value = { lineId: lineStore.lineId as unknown as string, alertType: '', - deviceInfos: [], - status: '', - groupId: '', + groupList: [ + { + groupName: '测试组', + groupId: '', + status: '', + deviceInfos: [], + expanded: false, + }, + ], }; selectGraphic = []; } diff --git a/src/components/common/DraggableDialog.vue b/src/components/common/DraggableDialog.vue index 65310a8..31cc8f6 100644 --- a/src/components/common/DraggableDialog.vue +++ b/src/components/common/DraggableDialog.vue @@ -27,7 +27,7 @@ :style="`height: ${props.titleHeight}px;background: ${props.titleColor}`" >
{{ props.title }}
@@ -113,7 +113,7 @@ function onMouseUp() { startOffset.y = 0; } function onMouseDown(e: MouseEvent) { - if (headerRef.value?.$el !== e.target) return; + if (!e.target || !headerRef.value?.$el.contains(e.target)) return; startOffset.x = e.offsetX; startOffset.y = e.offsetY; start.x = e.clientX - offset.x; diff --git a/src/components/rangeConfigApp/RangeConfig.vue b/src/components/rangeConfigApp/RangeConfig.vue index a801c10..c92c2b1 100644 --- a/src/components/rangeConfigApp/RangeConfig.vue +++ b/src/components/rangeConfigApp/RangeConfig.vue @@ -94,7 +94,7 @@ const showRangeConfig = ref(true); const rangeConfig = reactive<{ areaName: string; deviceType: `${DeviceType}` | ''; - device: string[]; + device: number[]; alertTypes: string[]; }>({ areaName: '', @@ -184,15 +184,11 @@ watch( } return select; }) as JlGraphic[]; - if (rangeConfig.alertTypes[0] !== '一级联锁') { - selectGraphic.push(...deviceFilter); - } else if (deviceFilter.length) { - selectGraphic = [deviceFilter[0]]; - } + selectGraphic.push(...deviceFilter); selectGraphic = Array.from(new Set(selectGraphic)); getRangeConfigApp().updateSelected(...selectGraphic); device.value = selectGraphic.map((g) => g.code) as string[]; - rangeConfig.device = selectGraphic.map((g) => g.id) as string[]; + rangeConfig.device = selectGraphic.map((g) => g.id) as number[]; } } ); @@ -267,7 +263,7 @@ async function searchById(id: number) { (type) => (showAlertTypeData as never)[type + ''] ); const select: JlGraphic[] = []; - response.data.data.forEach((id: string) => { + response.data.data.forEach((id: number) => { const g = getRangeConfigApp().queryStore.queryById(id); select.push(g); device.value.push(g.code); diff --git a/src/drawApp/graphics/SectionInteraction.ts b/src/drawApp/graphics/SectionInteraction.ts index 2906369..ee63ffb 100644 --- a/src/drawApp/graphics/SectionInteraction.ts +++ b/src/drawApp/graphics/SectionInteraction.ts @@ -53,11 +53,11 @@ export class SectionData extends GraphicDataBase implements ISectionData { set sectionType(type: graphicData.Section.SectionType) { this.data.sectionType = type; } - get axleCountings(): string[] { - return this.data.axleCountings; + get axleCountings(): number[] { + return this.data.axleCountings.map((a) => Number(a)); } - set axleCountings(axleCountings: string[]) { - this.data.axleCountings = axleCountings; + set axleCountings(axleCountings: number[]) { + this.data.axleCountings = axleCountings.map((a) => a.toString()); } get children(): number[] { return this.data.children; diff --git a/src/graphics/section/Section.ts b/src/graphics/section/Section.ts index 499121d..3ab5e19 100644 --- a/src/graphics/section/Section.ts +++ b/src/graphics/section/Section.ts @@ -40,8 +40,8 @@ export interface ISectionData extends GraphicData { set pbRef(ref: IRelatedRefData | undefined); get sectionType(): SectionType; set sectionType(type: SectionType); - get axleCountings(): string[]; - set axleCountings(axleCountings: string[]); + get axleCountings(): number[]; + set axleCountings(axleCountings: number[]); get children(): number[]; set children(children: number[]); get destinationCode(): string; @@ -233,9 +233,11 @@ export class Section extends JlGraphic implements ILineGraphic { buildRelation() { this.relationManage.deleteRelationOfGraphicAndOtherType(this, Section.Type); + if (this.datas.sectionType === SectionType.TurnoutPhysical) return; /** 区段与区段 */ this.queryStore.queryByType
(Section.Type).forEach((section) => { if (section.id === this.id) return; + if (section.datas.sectionType === SectionType.TurnoutPhysical) return; let param: SectionPort[] = []; if ( @@ -346,7 +348,6 @@ export class Section extends JlGraphic implements ILineGraphic { }); } if ( - this.datas.children && this.datas.children && this.datas.sectionType === SectionType.TurnoutPhysical ) { diff --git a/src/graphics/section/SectionDrawAssistant.ts b/src/graphics/section/SectionDrawAssistant.ts index f6291f7..8a3ad65 100644 --- a/src/graphics/section/SectionDrawAssistant.ts +++ b/src/graphics/section/SectionDrawAssistant.ts @@ -123,7 +123,7 @@ export class SectionDraw extends GraphicDrawAssistant< } generateTurnoutSection() { - const turnoutIds: string[] = []; /* 已遍历的道岔id列表 */ + const turnoutIds: number[] = []; /* 已遍历的道岔id列表 */ const dfs = (turnout: Turnout) => { const axleCountings: AxleCounting[] = []; const turnouts: Turnout[] = []; @@ -173,6 +173,18 @@ export class SectionDraw extends GraphicDrawAssistant< turnoutPhysicalSectionData.axleCountings = result.axleCountings.map( (ac) => ac.datas.id ); + const exsit = this.app.queryStore + .queryByType
(Section.Type) + .filter((g) => g.datas.sectionType === SectionType.TurnoutPhysical) + .some( + (ts) => + ts.datas.axleCountings.every((id) => + turnoutPhysicalSectionData.axleCountings.includes(id) + ) && + ts.datas.axleCountings.length === + turnoutPhysicalSectionData.axleCountings.length + ); + if (exsit) return; turnoutPhysicalSectionData.children = result.turnouts.map( (t) => t.datas.id ); @@ -232,18 +244,25 @@ export class SectionGraphicHitArea implements IHitArea { function buildAbsorbablePositions(section: Section): AbsorbablePosition[] { const aps: AbsorbablePosition[] = []; - const sections = section.queryStore.queryByType
(Section.Type); - sections.forEach((other) => { - const [ps, pe] = [ - other.localToCanvasPoint(other.getStartPoint()), - other.localToCanvasPoint(other.getEndPoint()), - ]; - const { width, height } = section.getGraphicApp().canvas; - const xs = new AbsorbableLine({ x: 0, y: ps.y }, { x: width, y: ps.y }); - const ys = new AbsorbableLine({ x: ps.x, y: 0 }, { x: ps.x, y: height }); - const xe = new AbsorbableLine({ x: 0, y: pe.y }, { x: width, y: pe.y }); - const ye = new AbsorbableLine({ x: pe.x, y: 0 }, { x: pe.x, y: height }); - aps.push(xs, ys, xe, ye); + const [ps, pe] = [ + section.localToCanvasPoint(section.getStartPoint()), + section.localToCanvasPoint(section.getEndPoint()), + ]; + const { width, height } = section.getGraphicApp().canvas; + const xs = new AbsorbableLine({ x: 0, y: ps.y }, { x: width, y: ps.y }); + const ys = new AbsorbableLine({ x: ps.x, y: 0 }, { x: ps.x, y: height }); + const xe = new AbsorbableLine({ x: 0, y: pe.y }, { x: width, y: pe.y }); + const ye = new AbsorbableLine({ x: pe.x, y: 0 }, { x: pe.x, y: height }); + aps.push(xs, ys, xe, ye); + const sections = section.queryStore + .queryByType
(Section.Type) + .filter((g) => g.datas.sectionType == SectionType.Physical); + sections.forEach((item) => { + if (item.id !== section.id) { + item.localToCanvasPoints(...item.datas.points).forEach((p) => { + aps.push(new AbsorbablePoint(p)); + }); + } }); const turnouts = section.queryStore.queryByType(Turnout.Type); diff --git a/src/graphics/turnout/Turnout.ts b/src/graphics/turnout/Turnout.ts index c938cb0..3075798 100644 --- a/src/graphics/turnout/Turnout.ts +++ b/src/graphics/turnout/Turnout.ts @@ -13,7 +13,7 @@ import { epsilon, Vector2, } from 'jl-graphic'; -import { Section, SectionPort } from '../section/Section'; +import { Section, SectionPort, SectionType } from '../section/Section'; import { IRelatedRefData, createRelatedRefProto, @@ -541,39 +541,47 @@ export class Turnout extends JlGraphic { buildRelation(): void { this.relationManage.deleteRelationOfGraphic(this); + /** 道岔和区段 */ - this.queryStore.queryByType
(Section.Type).forEach((section) => { - this.getPortPoints().forEach((port, i) => { - if ( - distance2( - section.localToCanvasPoint(section.getStartPoint()), - this.localToCanvasPoint(port[port.length - 1]) - ) <= epsilon - ) { - this.relationManage.addRelation( - new GraphicRelationParam( - this, - [TurnoutPort.A, TurnoutPort.B, TurnoutPort.C][i] - ), - new GraphicRelationParam(section, SectionPort.A) - ); - } - if ( - distance2( - section.localToCanvasPoint(section.getEndPoint()), - this.localToCanvasPoint(port[port.length - 1]) - ) <= epsilon - ) { - this.relationManage.addRelation( - new GraphicRelationParam( - this, - [TurnoutPort.A, TurnoutPort.B, TurnoutPort.C][i] - ), - new GraphicRelationParam(section, SectionPort.B) - ); + this.queryStore.queryByType
(Section.Type) + .forEach((section) => { + if (section.datas.sectionType === SectionType.TurnoutPhysical) { + if (section.datas.children.includes(this.datas.id)) { + this.relationManage.addRelation(this, section) + } + return } + this.getPortPoints().forEach((port, i) => { + if ( + distance2( + section.localToCanvasPoint(section.getStartPoint()), + this.localToCanvasPoint(port[port.length - 1]) + ) <= epsilon + ) { + this.relationManage.addRelation( + new GraphicRelationParam( + this, + [TurnoutPort.A, TurnoutPort.B, TurnoutPort.C][i] + ), + new GraphicRelationParam(section, SectionPort.A) + ); + } + if ( + distance2( + section.localToCanvasPoint(section.getEndPoint()), + this.localToCanvasPoint(port[port.length - 1]) + ) <= epsilon + ) { + this.relationManage.addRelation( + new GraphicRelationParam( + this, + [TurnoutPort.A, TurnoutPort.B, TurnoutPort.C][i] + ), + new GraphicRelationParam(section, SectionPort.B) + ); + } + }); }); - }); /** 道岔和道岔 */ this.getPortPoints().forEach((thisPort, i) => { @@ -656,10 +664,13 @@ export class Turnout extends JlGraphic { } else { this.datas.pbRef = undefined; } + const pcRelation = this.relationManage .getRelationsOfGraphic(this) .find( (relation) => relation.getRelationParam(this).param === TurnoutPort.C + && (!(relation.getOtherGraphic(this) instanceof Section + && relation.getOtherGraphic
(this).datas.sectionType !== SectionType.TurnoutPhysical)) ); const pcDevice = pcRelation?.getOtherGraphic
(this); if (pcDevice) { diff --git a/src/pages/LineMonitorPage.vue b/src/pages/LineMonitorPage.vue index 2d9f584..ea9f355 100644 --- a/src/pages/LineMonitorPage.vue +++ b/src/pages/LineMonitorPage.vue @@ -1,6 +1,6 @@