Compare commits

..

7 Commits

Author SHA1 Message Date
joylink_fanyuhong
b0265ad86e Merge remote-tracking branch 'origin/develop' into local-test
All checks were successful
CI / Docker-Build (push) Successful in 2m29s
2024-03-27 14:15:44 +08:00
joylink_fanyuhong
43a8993eb9 Merge branch 'develop' of http://120.46.212.6:3000/joylink/rts-sim-testing-client into develop 2024-03-27 14:11:53 +08:00
joylink_fanyuhong
f21690988d 车库门调整 2024-03-27 14:11:49 +08:00
joylink_zhaoerwei
0a2641c20f 一键生成继电器修改:增加边界条件的判断 2024-03-27 13:43:00 +08:00
joylink_zhaoerwei
e2ac7e4ae5 继电器K变大写 2024-03-27 12:14:15 +08:00
joylink_fanyuhong
6e1b972d2f 同步 2024-03-26 17:32:28 +08:00
joylink_fanyuhong
ebcfbfd891 车库门添加操作&状态 2024-03-26 17:31:37 +08:00
15 changed files with 764 additions and 28 deletions

@ -1 +1 @@
Subproject commit 86b35d3ead9a269f812b105d8a30a43c019da8bc Subproject commit f9034ba53d9b201140e9e43dbe8f5b8faa21633a

View File

@ -430,3 +430,17 @@ export async function updateTrainConn(data: {
}) { }) {
return await api.post(`${UriBase}/train/conn`, data); return await api.post(`${UriBase}/train/conn`, data);
} }
/** 车库门参数修改 */
export async function ckmUpdateParams(data: {
simulationId: string;
mapId: number;
deviceId: number;
operation: request.Ckm.Operation;
param: {
force: request.Ckm.Force;
fault: request.Ckm.Fault;
};
}) {
return await api.put(`${UriBase}/ckm/operation`, data);
}

View File

@ -0,0 +1,151 @@
<!-- eslint-disable vue/no-mutating-props -->
<template>
<draggable-dialog
v-model="showCkmOperation"
seamless
title="车库门设置参数"
:width="380"
:height="0"
>
<template v-slot:footer>
<q-card>
<q-card-section>
<q-form ref="myForm" @submit="onCreate" class="q-gutter-md">
<q-input
dense
outlined
readonly
label="名称"
v-model="props.code"
/>
<div
class="q-gutter-sm"
style="border: 1px solid #ccc; border-radius: 3px"
>
<div>车库门强制</div>
<q-radio
v-for="option in ckmForceOption"
:key="option.value"
v-model="ckmForce"
:val="option.value"
:label="option.label"
/>
</div>
<div
class="q-gutter-sm"
style="border: 1px solid #ccc; border-radius: 3px"
>
<div>设置故障</div>
<q-radio
v-for="option in ckmFaultOption"
:key="option.value"
v-model="ckmFault"
:val="option.value"
:label="option.label"
/>
</div>
<q-card-actions align="right" class="text-primary">
<q-btn
flat
label="取消"
@click="showCkmOperation = false"
v-close-popup
/>
<q-btn flat label="确认" type="submit" />
</q-card-actions>
</q-form>
</q-card-section>
</q-card>
</template>
</draggable-dialog>
</template>
<script setup lang="ts">
import { QForm } from 'quasar';
import { ckmUpdateParams } from 'src/api/Simulation';
import DraggableDialog from 'src/components/common/DraggableDialog.vue';
import { request } from 'src/protos/request';
import { useLineStore } from 'src/stores/line-store';
import { errorNotify } from 'src/utils/CommonNotify';
import { onMounted, onUnmounted, ref } from 'vue';
const props = defineProps({
id: {
type: Number,
required: true,
},
code: {
type: String,
required: true,
},
ckmForceProp: {
type: Number,
required: true,
},
ckmFaultProp: {
type: Number,
required: true,
},
});
const lineStore = useLineStore();
const showCkmOperation = ref(true);
const ckmForce = ref<request.Ckm.Force>(0);
const ckmForceOption = [
{
label: '无强制',
value: request.Ckm.Force.F_NONE,
},
{
label: '强制开门',
value: request.Ckm.Force.F_KM,
},
{
label: '强制关门',
value: request.Ckm.Force.F_GM,
},
];
const ckmFault = ref<request.Ckm.Fault>(0);
const ckmFaultOption = [
{
label: '无故障',
value: request.Ckm.Fault.FA_NONE,
},
{
label: '设置故障物',
value: request.Ckm.Fault.FA_State_Loss,
},
];
onMounted(() => {
ckmForce.value = props.ckmForceProp;
ckmFault.value = props.ckmFaultProp;
});
const myForm = ref<QForm | null>(null);
function onCreate() {
myForm.value?.validate().then(async (res) => {
if (res) {
const obj = {
simulationId: lineStore?.simulationId || '',
mapId: lineStore.mapId as number,
deviceId: props.id,
operation: request.Ckm.Operation.SetParams,
param: {
force: ckmForce.value,
fault: ckmFault.value,
},
};
ckmUpdateParams(obj).catch((e) =>
errorNotify('车库门操作失败:' + e.title, e)
);
showCkmOperation.value = false;
}
});
}
onUnmounted(() => {
lineStore.deviceOpreratDialogInstance = null;
});
</script>
<style scoped></style>

View File

@ -23,7 +23,7 @@
:map-options="true" :map-options="true"
:emit-value="true" :emit-value="true"
@update:model-value="onUpdate" @update:model-value="onUpdate"
label="关联屏蔽门" label="关联车库门"
></q-select> ></q-select>
<q-select <q-select
outlined outlined

View File

@ -28,6 +28,9 @@
<transponder-state <transponder-state
v-else-if="lineStore.selectedGraphicType === Transponder.Type" v-else-if="lineStore.selectedGraphicType === Transponder.Type"
></transponder-state> ></transponder-state>
<garage-door-state
v-else-if="lineStore.selectedGraphicType === GarageDoor.Type"
></garage-door-state>
</div> </div>
</q-scroll-area> </q-scroll-area>
</template> </template>
@ -56,6 +59,8 @@ import SpksSwitchState from './states/SpksSwitchState.vue';
import { SpksSwitch } from 'src/graphics/spksSwitch/SpksSwitch'; import { SpksSwitch } from 'src/graphics/spksSwitch/SpksSwitch';
import TransponderState from './states/TransponderState.vue'; import TransponderState from './states/TransponderState.vue';
import { Transponder } from 'src/graphics/transponder/Transponder'; import { Transponder } from 'src/graphics/transponder/Transponder';
import { GarageDoor } from 'src/graphics/garageDoor/GarageDoor';
import GarageDoorState from './states/GarageDoorState.vue';
const lineStore = useLineStore(); const lineStore = useLineStore();
</script> </script>

View File

@ -0,0 +1,184 @@
<template>
<q-card flat bordered>
<q-card-section class="flex justify-between">
<div class="text-h6">车库门状态</div>
<q-btn-dropdown color="primary" label="操作">
<q-list>
<q-item
v-for="(item, index) in operationOptions"
:key="index"
clickable
v-close-popup
@click="doGarageDoorOperation(item)"
>
<q-item-section>
<q-item-label>{{ item.label }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</q-card-section>
<q-separator inset />
<q-card-section>
<q-list dense>
<q-item v-for="(item, index) in list" :key="index">
<q-item-section>
<q-item-label>{{ item.label }}</q-item-label>
</q-item-section>
<q-item-section side>
<q-item-label caption>{{
item.formatFn
? item.formatFn(garageDoorState[item.key])
: garageDoorState[item.key]
}}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card-section>
</q-card>
</template>
<script setup lang="ts">
import { useLineStore } from 'src/stores/line-store';
import { ref, watch, onMounted, onUnmounted, toRaw } from 'vue';
import { request } from 'src/protos/request';
import { GarageDoor } from 'src/graphics/garageDoor/GarageDoor';
import CkmOperation from 'src/components/draw-app/dialogs/CkmOperation.vue';
import { GarageDoorState } from 'src/drawApp/graphics/GarageDoorInteraction';
import { Dialog } from 'quasar';
const lineStore = useLineStore();
const garageDoorState = ref<GarageDoorState>(new GarageDoorState());
const code = ref('');
const operationOptions = [
{
label: '设置参数',
value: request.Ckm.Operation.SetParams,
},
];
const garageDoorForce = ref<request.Ckm.Force>(0);
const garageDoorForceOption = [
{
label: '无强制',
value: request.Ckm.Force.F_NONE,
},
{
label: '强制开门',
value: request.Ckm.Force.F_KM,
},
{
label: '强制关门',
value: request.Ckm.Force.F_GM,
},
];
const garageDoorFault = ref<request.Ckm.Fault>(0);
let copySelectGraphic: GarageDoor | null = null;
interface KeyType {
label: string;
key: keyof GarageDoorState;
formatFn?(v: GarageDoorState[keyof GarageDoorState]): string;
}
const list: KeyType[] = [
{ label: '车库门索引', key: 'id' },
{ label: '车库门名称', key: 'code', formatFn: getNameFormat },
{ label: '车库门关闭', key: 'mgj', formatFn: getName },
{ label: '状态丢失', key: 'stateLoss', formatFn: getName },
{ label: '车库门强制', key: 'param', formatFn: getForceName },
{ label: '设置故障', key: 'param', formatFn: getFaultName },
];
watch(
() => lineStore.selectedGraphics,
(val, oldVal) => {
if (oldVal?.length == 1 && oldVal[0] instanceof GarageDoor) {
unSubscribeState(oldVal[0]);
}
if (val?.length == 1 && val[0] instanceof GarageDoor) {
copySelectGraphic = toRaw(val[0]);
initGarageDoorState(val[0]);
} else {
copySelectGraphic = null;
garageDoorState.value = new GarageDoorState();
}
}
);
onMounted(() => {
if (lineStore.selectedGraphics) {
initGarageDoorState(lineStore.selectedGraphics[0] as GarageDoor);
}
});
function getNameFormat() {
return code.value;
}
function getName(v: boolean) {
if (v) return '是';
return '否';
}
function getForceName() {
return (
garageDoorForceOption.find((item) => item.value == garageDoorForce.value)
?.label || ''
);
}
function getFaultName() {
if (garageDoorFault.value == 1) return '是';
return '否';
}
function initGarageDoorState(garageDoor: GarageDoor) {
copySelectGraphic = toRaw(garageDoor);
code.value = garageDoor.datas.code;
updateState(garageDoor);
subscribeState(garageDoor);
}
function updateState(garageDoor: GarageDoor) {
garageDoorState.value = garageDoor.states.clone() as GarageDoorState;
garageDoorForce.value = garageDoorState.value.param.force;
garageDoorFault.value = garageDoorState.value.param.fault;
}
function doGarageDoorOperation(item: {
label: string;
value: request.Ckm.Operation;
}) {
if (!lineStore.simulationId) return;
if (item.label == '设置参数') {
if (lineStore.deviceOpreratDialogInstance) return;
lineStore.deviceOpreratDialogInstance = Dialog.create({
component: CkmOperation,
componentProps: {
id: +garageDoorState.value.id,
code: code.value,
ckmForceProp: garageDoorState.value.param.force,
ckmFaultProp: garageDoorState.value.param.fault,
},
cancel: true,
persistent: true,
}).onCancel(() => {
lineStore.deviceOpreratDialogInstance = null;
});
}
}
function subscribeState(g: GarageDoor) {
g.on('stateupdate', updateState);
}
function unSubscribeState(g: GarageDoor) {
g.off('stateupdate', updateState);
}
onUnmounted(() => {
if (copySelectGraphic) {
unSubscribeState(copySelectGraphic);
}
});
</script>

View File

@ -7,7 +7,7 @@ function getHost(): string {
// return '192.168.3.7:9091'; // return '192.168.3.7:9091';
// return '192.168.3.47:9091'; // return '192.168.3.47:9091';
// return '192.168.3.37:9091'; // return '192.168.3.37:9091';
// return '192.168.33.207:9091'; // 张骞 return '192.168.33.207:9091'; // 张骞
// return '192.168.33.93:9091'; // return '192.168.33.93:9091';
// return '192.168.3.37:9091'; //卫志宏 // return '192.168.3.37:9091'; //卫志宏
// return 'test.joylink.club/bjrtsts-service'; // 测试 // return 'test.joylink.club/bjrtsts-service'; // 测试

View File

@ -160,7 +160,10 @@ import { CarWashingDraw } from 'src/graphics/carWashing/CarWashingDrawAssistant'
import { FloodGateData } from './graphics/FloodGateInteraction'; import { FloodGateData } from './graphics/FloodGateInteraction';
import { FloodGate, FloodGateTemplate } from 'src/graphics/floodGate/FloodGate'; import { FloodGate, FloodGateTemplate } from 'src/graphics/floodGate/FloodGate';
import { FloodGateDraw } from 'src/graphics/floodGate/FloodGateDrawAssistant'; import { FloodGateDraw } from 'src/graphics/floodGate/FloodGateDrawAssistant';
import { GarageDoorData } from './graphics/GarageDoorInteraction'; import {
GarageDoorData,
GarageDoorState,
} from './graphics/GarageDoorInteraction';
import { import {
GarageDoor, GarageDoor,
GarageDoorTemplate, GarageDoorTemplate,
@ -258,7 +261,10 @@ export function initCommonDrawApp(app: IDrawApp) {
); );
new CarWashingDraw(app, new CarWashingTemplate(new CarWashingData())); new CarWashingDraw(app, new CarWashingTemplate(new CarWashingData()));
new FloodGateDraw(app, new FloodGateTemplate(new FloodGateData())); new FloodGateDraw(app, new FloodGateTemplate(new FloodGateData()));
new GarageDoorDraw(app, new GarageDoorTemplate(new GarageDoorData())); new GarageDoorDraw(
app,
new GarageDoorTemplate(new GarageDoorData(), new GarageDoorState())
);
DrawSignalInteraction.init(app); DrawSignalInteraction.init(app);
DrawStopPositionInteraction.init(app); DrawStopPositionInteraction.init(app);
DrawSpksSwitchInteraction.init(app); DrawSpksSwitchInteraction.init(app);

View File

@ -1,13 +1,26 @@
import * as pb_1 from 'google-protobuf'; import * as pb_1 from 'google-protobuf';
import { FederatedMouseEvent } from 'pixi.js'; import { DisplayObject, FederatedMouseEvent } from 'pixi.js';
import { import {
GarageDoor, GarageDoor,
IGarageDoorData, IGarageDoorData,
IGarageDoorState,
} from 'src/graphics/garageDoor/GarageDoor'; } from 'src/graphics/garageDoor/GarageDoor';
import { GraphicInteractionPlugin, JlGraphic, IGraphicScene } from 'jl-graphic'; import {
GraphicInteractionPlugin,
JlGraphic,
IGraphicScene,
MenuItemOptions,
ContextMenu,
} from 'jl-graphic';
import { graphicData } from 'src/protos/stationLayoutGraphics'; import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase'; import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
import { useLineStore } from 'src/stores/line-store';
import { Dialog } from 'quasar';
import CkmOperation from 'src/components/draw-app/dialogs/CkmOperation.vue';
import { state } from 'src/protos/device_state';
import { request } from 'src/protos/request';
import { GarageDoorGraphicHitArea } from 'src/graphics/garageDoor/GarageDoorDrawAssistant';
export class GarageDoorData extends GraphicDataBase implements IGarageDoorData { export class GarageDoorData extends GraphicDataBase implements IGarageDoorData {
constructor(data?: graphicData.GarageDoor) { constructor(data?: graphicData.GarageDoor) {
@ -54,35 +67,116 @@ export class GarageDoorData extends GraphicDataBase implements IGarageDoorData {
} }
} }
export class GarageDoorState
extends GraphicStateBase
implements IGarageDoorState
{
constructor(proto?: state.CkmState) {
let states;
if (proto) {
states = proto;
} else {
states = new state.CkmState();
}
super(states, GarageDoor.Type);
}
get code(): string {
return this.states.id + '';
}
get id(): number {
return this.states.id;
}
set id(id: number) {
this.states.id = id;
}
get mgj() {
return this.states.mgj;
}
set mgj(v: boolean) {
this.states.mgj = v;
}
get stateLoss(): boolean {
//状态丢失
return this.states.stateLoss;
}
set stateLoss(v: boolean) {
this.states.stateLoss = v;
}
get param(): request.CkmParam {
return this.states.param;
}
set param(param: request.CkmParam) {
this.states.param = param;
}
get states(): state.CkmState {
return this.getState<state.CkmState>();
}
clone(): GarageDoorState {
return new GarageDoorState(this.states.cloneMessage());
}
copyFrom(data: GraphicStateBase): void {
pb_1.Message.copyInto(data._state, this._state);
}
eq(data: GraphicStateBase): boolean {
return pb_1.Message.equals(this._state, data._state);
}
}
const setCkmrParam: MenuItemOptions = { name: '设置参数' };
const ckmOperateMenu: ContextMenu = ContextMenu.init({
name: '屏蔽门操作菜单',
groups: [
{
items: [setCkmrParam],
},
],
});
export class GarageDoorOperationInteraction extends GraphicInteractionPlugin<GarageDoor> { export class GarageDoorOperationInteraction extends GraphicInteractionPlugin<GarageDoor> {
static Name = 'garage_door_operation'; static Name = 'garage_door_operation';
constructor(scene: IGraphicScene) { constructor(app: IGraphicScene) {
super(GarageDoorOperationInteraction.Name, scene); super(GarageDoorOperationInteraction.Name, app);
app.registerMenu(ckmOperateMenu);
} }
static init(scene: IGraphicScene) { static init(app: IGraphicScene) {
return new GarageDoorOperationInteraction(scene); return new GarageDoorOperationInteraction(app);
} }
filter(...grahpics: JlGraphic[]): GarageDoor[] | undefined { filter(...grahpics: JlGraphic[]): GarageDoor[] | undefined {
return grahpics.filter((g): g is GarageDoor => g.type === GarageDoor.Type); return grahpics.filter((g): g is GarageDoor => g.type === GarageDoor.Type);
} }
bind(g: GarageDoor): void { bind(g: GarageDoor): void {
g.eventMode = 'static'; g.eventMode = 'static';
g.hitArea = new GarageDoorGraphicHitArea(g);
g.cursor = 'pointer'; g.cursor = 'pointer';
g.on('mousedown', this.onPress, this); g.selectable = true;
g.on('_rightclick', this.onContextMenu);
} }
unbind(g: GarageDoor): void { unbind(g: GarageDoor): void {
g.eventMode = 'none'; g.eventMode = 'none';
g.cursor = 'default'; g.cursor = 'default';
g.off('mousedown', this.onPress, this); g.selectable = false;
g.off('_rightclick', this.onContextMenu);
} }
onPress(e: FederatedMouseEvent) {
const g = e.target as GarageDoor; onContextMenu(e: FederatedMouseEvent) {
g.on('mouseleave', this.onRelease, this); const target = e.target as DisplayObject;
g.on('mouseup', this.onRelease, this); const garageDoor = target.getGraphic<GarageDoor>();
} if (!garageDoor) return;
onRelease(e: FederatedMouseEvent) { const lineStore = useLineStore();
const g = e.target as GarageDoor; setCkmrParam.handler = async () => {
g.off('mouseleave', this.onRelease, this); if (lineStore.deviceOpreratDialogInstance) return;
g.off('mouseup', this.onRelease, this); lineStore.deviceOpreratDialogInstance = Dialog.create({
component: CkmOperation,
componentProps: {
id: garageDoor.id,
code: garageDoor.datas.code,
ckmForceProp: garageDoor.states.param.force,
ckmFaultProp: garageDoor.states.param.fault,
},
cancel: true,
persistent: true,
});
};
ckmOperateMenu.open(e.global);
} }
} }

View File

@ -37,6 +37,7 @@ import {
import { import {
GarageDoorData, GarageDoorData,
GarageDoorOperationInteraction, GarageDoorOperationInteraction,
GarageDoorState,
} from './graphics/GarageDoorInteraction'; } from './graphics/GarageDoorInteraction';
import { import {
GarageDoor, GarageDoor,
@ -333,7 +334,7 @@ export function initLineScene(lineApp: IGraphicApp, sceneName: string) {
new AutoReturnBoxState() new AutoReturnBoxState()
), ),
new CarWashingTemplate(new CarWashingData()), new CarWashingTemplate(new CarWashingData()),
new GarageDoorTemplate(new GarageDoorData()), new GarageDoorTemplate(new GarageDoorData(), new GarageDoorState()),
new FloodGateTemplate(new FloodGateData()), new FloodGateTemplate(new FloodGateData()),
new GarageDoorBoxTemplate(new GarageDoorBoxData()), new GarageDoorBoxTemplate(new GarageDoorBoxData()),
]; ];
@ -461,6 +462,11 @@ function handleSubscribe(lineScene: IGraphicScene) {
states.push(new TransponderState(item)); states.push(new TransponderState(item));
} }
}); });
storage.allStatus.ckmStates.forEach((item) => {
if (item.id) {
states.push(new GarageDoorState(item));
}
});
storage.allStatus.trainState.forEach((item) => { storage.allStatus.trainState.forEach((item) => {
// 列车 // 列车
if (!item.show) { if (!item.show) {

View File

@ -4,7 +4,9 @@ import {
JlGraphic, JlGraphic,
JlGraphicTemplate, JlGraphicTemplate,
VectorText, VectorText,
linePoint,
} from 'jl-graphic'; } from 'jl-graphic';
import { Section, SectionType } from '../section/Section';
export interface ICarWashingData extends GraphicData { export interface ICarWashingData extends GraphicData {
get code(): string; get code(): string;
@ -75,6 +77,30 @@ export class CarWashing extends JlGraphic {
); );
this.rectBody.endFill(); this.rectBody.endFill();
} }
buildRelation() {
const sections = this.queryStore
.queryByType<Section>(Section.Type)
.filter((s) => s.datas.sectionType === SectionType.Physical);
let xj = false;
const se = sections.find((section) => {
const points = section.linePoints;
points.forEach((point, index) => {
if (index !== 0) {
xj =
linePoint(
section.localToCanvasPoint(points[index - 1]),
section.localToCanvasPoint(point),
this.localToCanvasPoint({ x: 0, y: 0 }),
8
) || xj;
}
});
return xj;
});
if (se) {
this.datas.linkSection = se.datas.id;
}
}
} }
export class CarWashingTemplate extends JlGraphicTemplate<CarWashing> { export class CarWashingTemplate extends JlGraphicTemplate<CarWashing> {

View File

@ -4,7 +4,9 @@ import {
JlGraphic, JlGraphic,
JlGraphicTemplate, JlGraphicTemplate,
VectorText, VectorText,
linePoint,
} from 'jl-graphic'; } from 'jl-graphic';
import { Section, SectionType } from '../section/Section';
export interface IFloodGateData extends GraphicData { export interface IFloodGateData extends GraphicData {
get code(): string; get code(): string;
@ -85,6 +87,31 @@ export class FloodGate extends JlGraphic {
this.lineBody.moveTo(0, -floodGateConsts.bodyRectHeight / 2); this.lineBody.moveTo(0, -floodGateConsts.bodyRectHeight / 2);
this.lineBody.lineTo(0, floodGateConsts.bodyRectHeight / 2); this.lineBody.lineTo(0, floodGateConsts.bodyRectHeight / 2);
} }
buildRelation() {
const sections = this.queryStore
.queryByType<Section>(Section.Type)
.filter((s) => s.datas.sectionType === SectionType.Physical);
let xj = false;
const se = sections.find((section) => {
const points = section.linePoints;
points.forEach((point, index) => {
if (index !== 0) {
xj =
linePoint(
section.localToCanvasPoint(points[index - 1]),
section.localToCanvasPoint(point),
this.localToCanvasPoint({ x: 0, y: 0 }),
8
) || xj;
}
});
return xj;
});
if (se) {
this.datas.linkSection = se.datas.id;
}
}
} }
export class FloodGateTemplate extends JlGraphicTemplate<FloodGate> { export class FloodGateTemplate extends JlGraphicTemplate<FloodGate> {

View File

@ -1,10 +1,14 @@
import { Graphics } from 'pixi.js'; import { Graphics } from 'pixi.js';
import { import {
GraphicData, GraphicData,
GraphicState,
JlGraphic, JlGraphic,
JlGraphicTemplate, JlGraphicTemplate,
VectorText, VectorText,
linePoint,
} from 'jl-graphic'; } from 'jl-graphic';
import { request } from 'src/protos/request';
import { Section, SectionType } from '../section/Section';
export interface IGarageDoorData extends GraphicData { export interface IGarageDoorData extends GraphicData {
get code(): string; get code(): string;
@ -18,6 +22,17 @@ export interface IGarageDoorData extends GraphicData {
eq(other: IGarageDoorData): boolean; eq(other: IGarageDoorData): boolean;
} }
export interface IGarageDoorState extends GraphicState {
get id(): number;
set id(v: number);
get mgj(): boolean; //车库门关闭继电器
set mgj(v: boolean);
get param(): request.CkmParam;
set param(v: request.CkmParam);
get stateLoss(): boolean; //状态丢失
set stateLoss(v: boolean);
}
const garageConsts = { const garageConsts = {
codeFontSize: 12, codeFontSize: 12,
codeColor: 0xffffff, codeColor: 0xffffff,
@ -44,6 +59,10 @@ export class GarageDoor extends JlGraphic {
get datas(): IGarageDoorData { get datas(): IGarageDoorData {
return this.getDatas<IGarageDoorData>(); return this.getDatas<IGarageDoorData>();
} }
get states(): IGarageDoorState {
return this.getStates<IGarageDoorState>();
}
doRepaint(): void { doRepaint(): void {
const codeGraph = this.codeGraph; const codeGraph = this.codeGraph;
codeGraph.text = this.datas.code; codeGraph.text = this.datas.code;
@ -85,15 +104,41 @@ export class GarageDoor extends JlGraphic {
this.lineBody.moveTo(0, -garageConsts.bodyRectHeight / 2); this.lineBody.moveTo(0, -garageConsts.bodyRectHeight / 2);
this.lineBody.lineTo(0, garageConsts.bodyRectHeight / 2); this.lineBody.lineTo(0, garageConsts.bodyRectHeight / 2);
} }
buildRelation() {
const sections = this.queryStore
.queryByType<Section>(Section.Type)
.filter((s) => s.datas.sectionType === SectionType.Physical);
let xj = false;
const se = sections.find((section) => {
const points = section.linePoints;
points.forEach((point, index) => {
if (index !== 0) {
xj =
linePoint(
section.localToCanvasPoint(points[index - 1]),
section.localToCanvasPoint(point),
this.localToCanvasPoint({ x: 0, y: 0 }),
8
) || xj;
}
});
return xj;
});
if (se) {
this.datas.linkSection = se.datas.id;
}
}
} }
export class GarageDoorTemplate extends JlGraphicTemplate<GarageDoor> { export class GarageDoorTemplate extends JlGraphicTemplate<GarageDoor> {
constructor(dataTemplate: IGarageDoorData) { constructor(dataTemplate: IGarageDoorData, stateTemplate?: IGarageDoorState) {
super(GarageDoor.Type, { dataTemplate }); super(GarageDoor.Type, { dataTemplate, stateTemplate });
} }
new(): GarageDoor { new(): GarageDoor {
const garageDoor = new GarageDoor(); const garageDoor = new GarageDoor();
garageDoor.loadData(this.datas); garageDoor.loadData(this.datas);
garageDoor.loadState(this.states);
return garageDoor; return garageDoor;
} }
} }

View File

@ -1,4 +1,4 @@
import { DisplayObject, FederatedMouseEvent, Point } from 'pixi.js'; import { DisplayObject, FederatedMouseEvent, Point, IHitArea } from 'pixi.js';
import { import {
AbsorbableLine, AbsorbableLine,
AbsorbablePosition, AbsorbablePosition,
@ -82,6 +82,21 @@ function buildAbsorbablePositions(
return aps; return aps;
} }
export class GarageDoorGraphicHitArea implements IHitArea {
garageDoor: GarageDoor;
constructor(garageDoor: GarageDoor) {
this.garageDoor = garageDoor;
}
contains(x: number, y: number): boolean {
const bound = this.garageDoor.getLocalBounds();
const maxX = bound.x + bound.width;
const minX = bound.x;
const maxY = bound.y + bound.height;
const minY = bound.y;
return maxX >= x && x >= minX && maxY >= y && y >= minY;
}
}
export class GarageDoorInteraction extends GraphicInteractionPlugin<GarageDoor> { export class GarageDoorInteraction extends GraphicInteractionPlugin<GarageDoor> {
static Name = 'garage_door_transform'; static Name = 'garage_door_transform';
constructor(app: IDrawApp) { constructor(app: IDrawApp) {
@ -100,6 +115,7 @@ export class GarageDoorInteraction extends GraphicInteractionPlugin<GarageDoor>
g.cursor = 'pointer'; g.cursor = 'pointer';
g.scalable = true; g.scalable = true;
g.rotatable = true; g.rotatable = true;
g.hitArea = new GarageDoorGraphicHitArea(g);
g.codeGraph.draggable = true; g.codeGraph.draggable = true;
g.codeGraph.selectable = true; g.codeGraph.selectable = true;
g.codeGraph.rotatable = true; g.codeGraph.rotatable = true;

View File

@ -6873,6 +6873,145 @@ export namespace state {
} }
} }
} }
export class CkmState extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
id?: number;
mgj?: boolean;
param?: dependency_3.request.CkmParam;
stateLoss?: boolean;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("id" in data && data.id != undefined) {
this.id = data.id;
}
if ("mgj" in data && data.mgj != undefined) {
this.mgj = data.mgj;
}
if ("param" in data && data.param != undefined) {
this.param = data.param;
}
if ("stateLoss" in data && data.stateLoss != undefined) {
this.stateLoss = data.stateLoss;
}
}
}
get id() {
return pb_1.Message.getFieldWithDefault(this, 1, 0) as number;
}
set id(value: number) {
pb_1.Message.setField(this, 1, value);
}
get mgj() {
return pb_1.Message.getFieldWithDefault(this, 2, false) as boolean;
}
set mgj(value: boolean) {
pb_1.Message.setField(this, 2, value);
}
get param() {
return pb_1.Message.getWrapperField(this, dependency_3.request.CkmParam, 3) as dependency_3.request.CkmParam;
}
set param(value: dependency_3.request.CkmParam) {
pb_1.Message.setWrapperField(this, 3, value);
}
get has_param() {
return pb_1.Message.getField(this, 3) != null;
}
get stateLoss() {
return pb_1.Message.getFieldWithDefault(this, 4, false) as boolean;
}
set stateLoss(value: boolean) {
pb_1.Message.setField(this, 4, value);
}
static fromObject(data: {
id?: number;
mgj?: boolean;
param?: ReturnType<typeof dependency_3.request.CkmParam.prototype.toObject>;
stateLoss?: boolean;
}): CkmState {
const message = new CkmState({});
if (data.id != null) {
message.id = data.id;
}
if (data.mgj != null) {
message.mgj = data.mgj;
}
if (data.param != null) {
message.param = dependency_3.request.CkmParam.fromObject(data.param);
}
if (data.stateLoss != null) {
message.stateLoss = data.stateLoss;
}
return message;
}
toObject() {
const data: {
id?: number;
mgj?: boolean;
param?: ReturnType<typeof dependency_3.request.CkmParam.prototype.toObject>;
stateLoss?: boolean;
} = {};
if (this.id != null) {
data.id = this.id;
}
if (this.mgj != null) {
data.mgj = this.mgj;
}
if (this.param != null) {
data.param = this.param.toObject();
}
if (this.stateLoss != null) {
data.stateLoss = this.stateLoss;
}
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.id != 0)
writer.writeUint32(1, this.id);
if (this.mgj != false)
writer.writeBool(2, this.mgj);
if (this.has_param)
writer.writeMessage(3, this.param, () => this.param.serialize(writer));
if (this.stateLoss != false)
writer.writeBool(4, this.stateLoss);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): CkmState {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new CkmState();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
message.id = reader.readUint32();
break;
case 2:
message.mgj = reader.readBool();
break;
case 3:
reader.readMessage(message.param, () => message.param = dependency_3.request.CkmParam.deserialize(reader));
break;
case 4:
message.stateLoss = reader.readBool();
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): CkmState {
return CkmState.deserialize(bytes);
}
}
export class VariationStatus extends pb_1.Message { export class VariationStatus extends pb_1.Message {
#one_of_decls: number[][] = []; #one_of_decls: number[][] = [];
constructor(data?: any[] | { constructor(data?: any[] | {
@ -7048,9 +7187,10 @@ export namespace state {
platformState?: PlatformState[]; platformState?: PlatformState[];
baliseState?: BaliseState[]; baliseState?: BaliseState[];
stationQc?: StationQc; stationQc?: StationQc;
ckmStates?: CkmState[];
}) { }) {
super(); super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], this.#one_of_decls); pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") { if (!Array.isArray(data) && typeof data == "object") {
if ("trainState" in data && data.trainState != undefined) { if ("trainState" in data && data.trainState != undefined) {
this.trainState = data.trainState; this.trainState = data.trainState;
@ -7091,6 +7231,9 @@ export namespace state {
if ("stationQc" in data && data.stationQc != undefined) { if ("stationQc" in data && data.stationQc != undefined) {
this.stationQc = data.stationQc; this.stationQc = data.stationQc;
} }
if ("ckmStates" in data && data.ckmStates != undefined) {
this.ckmStates = data.ckmStates;
}
} }
} }
get trainState() { get trainState() {
@ -7174,6 +7317,12 @@ export namespace state {
get has_stationQc() { get has_stationQc() {
return pb_1.Message.getField(this, 13) != null; return pb_1.Message.getField(this, 13) != null;
} }
get ckmStates() {
return pb_1.Message.getRepeatedWrapperField(this, CkmState, 14) as CkmState[];
}
set ckmStates(value: CkmState[]) {
pb_1.Message.setRepeatedWrapperField(this, 14, value);
}
static fromObject(data: { static fromObject(data: {
trainState?: ReturnType<typeof TrainMapState.prototype.toObject>[]; trainState?: ReturnType<typeof TrainMapState.prototype.toObject>[];
switchState?: ReturnType<typeof SwitchState.prototype.toObject>[]; switchState?: ReturnType<typeof SwitchState.prototype.toObject>[];
@ -7188,6 +7337,7 @@ export namespace state {
platformState?: ReturnType<typeof PlatformState.prototype.toObject>[]; platformState?: ReturnType<typeof PlatformState.prototype.toObject>[];
baliseState?: ReturnType<typeof BaliseState.prototype.toObject>[]; baliseState?: ReturnType<typeof BaliseState.prototype.toObject>[];
stationQc?: ReturnType<typeof StationQc.prototype.toObject>; stationQc?: ReturnType<typeof StationQc.prototype.toObject>;
ckmStates?: ReturnType<typeof CkmState.prototype.toObject>[];
}): AllDevicesStatus { }): AllDevicesStatus {
const message = new AllDevicesStatus({}); const message = new AllDevicesStatus({});
if (data.trainState != null) { if (data.trainState != null) {
@ -7229,6 +7379,9 @@ export namespace state {
if (data.stationQc != null) { if (data.stationQc != null) {
message.stationQc = StationQc.fromObject(data.stationQc); message.stationQc = StationQc.fromObject(data.stationQc);
} }
if (data.ckmStates != null) {
message.ckmStates = data.ckmStates.map(item => CkmState.fromObject(item));
}
return message; return message;
} }
toObject() { toObject() {
@ -7246,6 +7399,7 @@ export namespace state {
platformState?: ReturnType<typeof PlatformState.prototype.toObject>[]; platformState?: ReturnType<typeof PlatformState.prototype.toObject>[];
baliseState?: ReturnType<typeof BaliseState.prototype.toObject>[]; baliseState?: ReturnType<typeof BaliseState.prototype.toObject>[];
stationQc?: ReturnType<typeof StationQc.prototype.toObject>; stationQc?: ReturnType<typeof StationQc.prototype.toObject>;
ckmStates?: ReturnType<typeof CkmState.prototype.toObject>[];
} = {}; } = {};
if (this.trainState != null) { if (this.trainState != null) {
data.trainState = this.trainState.map((item: TrainMapState) => item.toObject()); data.trainState = this.trainState.map((item: TrainMapState) => item.toObject());
@ -7286,6 +7440,9 @@ export namespace state {
if (this.stationQc != null) { if (this.stationQc != null) {
data.stationQc = this.stationQc.toObject(); data.stationQc = this.stationQc.toObject();
} }
if (this.ckmStates != null) {
data.ckmStates = this.ckmStates.map((item: CkmState) => item.toObject());
}
return data; return data;
} }
serialize(): Uint8Array; serialize(): Uint8Array;
@ -7318,6 +7475,8 @@ export namespace state {
writer.writeRepeatedMessage(12, this.baliseState, (item: BaliseState) => item.serialize(writer)); writer.writeRepeatedMessage(12, this.baliseState, (item: BaliseState) => item.serialize(writer));
if (this.has_stationQc) if (this.has_stationQc)
writer.writeMessage(13, this.stationQc, () => this.stationQc.serialize(writer)); writer.writeMessage(13, this.stationQc, () => this.stationQc.serialize(writer));
if (this.ckmStates.length)
writer.writeRepeatedMessage(14, this.ckmStates, (item: CkmState) => item.serialize(writer));
if (!w) if (!w)
return writer.getResultBuffer(); return writer.getResultBuffer();
} }
@ -7366,6 +7525,9 @@ export namespace state {
case 13: case 13:
reader.readMessage(message.stationQc, () => message.stationQc = StationQc.deserialize(reader)); reader.readMessage(message.stationQc, () => message.stationQc = StationQc.deserialize(reader));
break; break;
case 14:
reader.readMessage(message.ckmStates, () => pb_1.Message.addToRepeatedWrapperField(message, 14, CkmState.deserialize(reader), CkmState));
break;
default: reader.skipField(); default: reader.skipField();
} }
} }