增加列车驾驶台图--壳
This commit is contained in:
parent
b6c031d7b9
commit
309931be31
39
src/components/draw-app/TccDrawProperties.vue
Normal file
39
src/components/draw-app/TccDrawProperties.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<!-- 画布或图形对象属性 -->
|
||||
<div v-if="tccDrawStore.selectedGraphics !== null">
|
||||
<q-card flat>
|
||||
<q-card-section>
|
||||
<div class="text-h6">
|
||||
{{ tccDrawStore.selectedObjName + ' 属性' }}
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator inset></q-separator>
|
||||
<template v-if="tccDrawStore.selectedGraphics.length === 0">
|
||||
<q-card-section>
|
||||
<canvas-tcc-property></canvas-tcc-property>
|
||||
</q-card-section>
|
||||
</template>
|
||||
<template v-else-if="tccDrawStore.selectedGraphics.length === 1">
|
||||
<q-card-section>
|
||||
<tcc-button-property
|
||||
v-if="tccDrawStore.selectedGraphicType === TccButton.Type"
|
||||
></tcc-button-property>
|
||||
<tcc-text-property
|
||||
v-if="tccDrawStore.selectedGraphicType === TextContent.Type"
|
||||
></tcc-text-property>
|
||||
</q-card-section>
|
||||
</template>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useTccDrawStore } from 'src/stores/tcc-draw-store';
|
||||
import CanvasTccProperty from './properties/CanvasTccProperty.vue';
|
||||
import { TccButton } from 'src/graphics/tccButton/TccButton';
|
||||
import TccButtonProperty from './properties/TccButtonProperty.vue';
|
||||
import { TextContent } from 'src/graphics/textContent/TextContent';
|
||||
import TccTextProperty from './properties/TccTextProperty.vue';
|
||||
|
||||
const tccDrawStore = useTccDrawStore();
|
||||
</script>
|
80
src/components/draw-app/properties/CanvasTccProperty.vue
Normal file
80
src/components/draw-app/properties/CanvasTccProperty.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<q-form>
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="canvas.width"
|
||||
@blur="onUpdate"
|
||||
label="画布宽 *"
|
||||
lazy-rules
|
||||
:rules="[(val) => (val && val > 0) || '画布宽必须大于0']"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
outlined
|
||||
type="number"
|
||||
v-model.number="canvas.height"
|
||||
@blur="onUpdate"
|
||||
label="画布高 *"
|
||||
lazy-rules
|
||||
:rules="[(val) => val > 0 || '画布高必须大于0']"
|
||||
/>
|
||||
|
||||
<q-input
|
||||
outlined
|
||||
v-model="canvas.backgroundColor"
|
||||
@blur="onUpdate"
|
||||
label="画布背景色 *"
|
||||
lazy-rules
|
||||
:rules="[(val) => (val && val.length > 0) || '画布背景色必须设置']"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="colorize" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-color
|
||||
:model-value="canvas.backgroundColor"
|
||||
@change="
|
||||
(val) => {
|
||||
canvas.backgroundColor = val;
|
||||
onUpdate();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useTccDrawStore } from 'src/stores/tcc-draw-store';
|
||||
import { onMounted, onUnmounted, reactive } from 'vue';
|
||||
const tccDrawStore = useTccDrawStore();
|
||||
|
||||
const canvas = reactive({
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
backgroundColor: '#ffffff',
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// console.log('画布属性表单mounted');
|
||||
const jc = tccDrawStore.getJlCanvas();
|
||||
canvas.width = jc.properties.width;
|
||||
canvas.height = jc.properties.height;
|
||||
canvas.backgroundColor = jc.properties.backgroundColor;
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
// console.log('画布属性表单unmounted');
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
// console.log('画布属性更新');
|
||||
const app = tccDrawStore.getDrawApp();
|
||||
app.updateCanvasAndRecord({
|
||||
...canvas,
|
||||
viewportTransform: app.canvas.properties.viewportTransform,
|
||||
});
|
||||
}
|
||||
</script>
|
43
src/components/draw-app/properties/TccButtonProperty.vue
Normal file
43
src/components/draw-app/properties/TccButtonProperty.vue
Normal file
@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input outlined readonly v-model="tccButtonModel.id" label="id" />
|
||||
<q-input
|
||||
outlined
|
||||
v-model="tccButtonModel.code"
|
||||
@blur="onUpdate"
|
||||
label="紧急制动按钮"
|
||||
lazy-rules
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
v-model="tccButtonModel.buttonColor"
|
||||
:options="optionsButtonColor"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="按钮颜色"
|
||||
/>
|
||||
<q-checkbox
|
||||
v-model="tccButtonModel.isSelfReset"
|
||||
label="是否自复位"
|
||||
@update:model-value="onUpdate"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { TccButtonData } from 'src/drawApp/graphics/TccButtonInteraction';
|
||||
import { tccGraphicData } from 'src/protos/tccGraphics';
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { useTccDrawStore } from 'src/stores/tcc-draw-store';
|
||||
|
||||
const { data: tccButtonModel, onUpdate } = useFormData(
|
||||
new TccButtonData(),
|
||||
useTccDrawStore().getDrawApp()
|
||||
);
|
||||
|
||||
const optionsButtonColor = [
|
||||
{ label: '绿色', value: tccGraphicData.TccElementColor.green },
|
||||
{ label: '红色', value: tccGraphicData.TccElementColor.red },
|
||||
];
|
||||
</script>
|
50
src/components/draw-app/properties/TccTextProperty.vue
Normal file
50
src/components/draw-app/properties/TccTextProperty.vue
Normal file
@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<q-form class="q-gutter-sm">
|
||||
<q-input outlined readonly v-model="textContentModel.id" label="id" />
|
||||
<q-input
|
||||
outlined
|
||||
v-model="textContentModel.content"
|
||||
@update:model-value="onUpdate"
|
||||
label="TCC文字内容"
|
||||
lazy-rules
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
v-model="textContentModel.color"
|
||||
@blur="onUpdate"
|
||||
label="TCC文字颜色"
|
||||
lazy-rules
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="colorize" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-color
|
||||
@update:model-value="onUpdate"
|
||||
v-model="textContentModel.color"
|
||||
/>
|
||||
</q-popup-proxy>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-input
|
||||
v-model.number="textContentModel.fontSize"
|
||||
type="number"
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
label="TCC文字大小"
|
||||
lazy-rules
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { TccTextData } from 'src/drawApp/graphics/TccTextContentInteraction';
|
||||
import { useTccDrawStore } from 'src/stores/tcc-draw-store';
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
|
||||
const tccDrawStore = useTccDrawStore();
|
||||
const { data: textContentModel, onUpdate } = useFormData(
|
||||
new TccTextData(),
|
||||
tccDrawStore.getDrawApp()
|
||||
);
|
||||
</script>
|
149
src/drawApp/graphics/TccButtonInteraction.ts
Normal file
149
src/drawApp/graphics/TccButtonInteraction.ts
Normal file
@ -0,0 +1,149 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { GraphicInteractionPlugin, IGraphicScene, JlGraphic } from 'jl-graphic';
|
||||
import { tccGraphicData } from 'src/protos/tccGraphics';
|
||||
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { DisplayObject, FederatedMouseEvent } from 'pixi.js';
|
||||
import { useTccStore } from 'src/stores/tcc-store';
|
||||
import { state } from 'src/protos/device_state';
|
||||
import { ITccButtonData, ITccButtonState, TccButton } from 'src/graphics/tccButton/TccButton';
|
||||
|
||||
export class TccButtonData extends GraphicDataBase implements ITccButtonData {
|
||||
constructor(data?: tccGraphicData.TccButton) {
|
||||
let tccButton;
|
||||
if (data) {
|
||||
tccButton = data;
|
||||
} else {
|
||||
tccButton = new tccGraphicData.TccButton({
|
||||
common: GraphicDataBase.defaultCommonInfo(TccButton.Type),
|
||||
});
|
||||
}
|
||||
super(tccButton);
|
||||
}
|
||||
|
||||
public get data(): tccGraphicData.TccButton {
|
||||
return this.getData<tccGraphicData.TccButton>();
|
||||
}
|
||||
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get buttonColor(): tccGraphicData.TccElementColor {
|
||||
return this.data.buttonColor;
|
||||
}
|
||||
set buttonColor(v: tccGraphicData.TccElementColor) {
|
||||
this.data.buttonColor = v;
|
||||
}
|
||||
get isSelfReset(): boolean {
|
||||
return this.data.isSelfReset;
|
||||
}
|
||||
set isSelfReset(v: boolean) {
|
||||
this.data.isSelfReset = v;
|
||||
}
|
||||
clone(): TccButtonData {
|
||||
return new TccButtonData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: TccButtonData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: TccButtonData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
||||
export class TccButtonState
|
||||
extends GraphicStateBase
|
||||
implements ITccButtonState
|
||||
{
|
||||
constructor(proto?: state.ButtonState) {
|
||||
let states;
|
||||
if (proto) {
|
||||
states = proto;
|
||||
} else {
|
||||
states = new state.ButtonState();
|
||||
}
|
||||
super(states, TccButton.Type);
|
||||
}
|
||||
get code(): string {
|
||||
return this.states.id + '';
|
||||
}
|
||||
get down(): boolean {
|
||||
return this.states.down;
|
||||
}
|
||||
set down(v: boolean) {
|
||||
this.states.down = v;
|
||||
}
|
||||
get states(): state.ButtonState {
|
||||
return this.getState<state.ButtonState>();
|
||||
}
|
||||
clone(): TccButtonState {
|
||||
return new TccButtonState(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);
|
||||
}
|
||||
}
|
||||
|
||||
export class TccButtonOperateInteraction extends GraphicInteractionPlugin<TccButton> {
|
||||
static Name = 'tcc_button_operate_menu';
|
||||
constructor(app: IGraphicScene) {
|
||||
super(TccButtonOperateInteraction.Name, app);
|
||||
}
|
||||
static init(app: IGraphicScene) {
|
||||
return new TccButtonOperateInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): TccButton[] | undefined {
|
||||
return grahpics
|
||||
.filter((g) => g.type === TccButton.Type)
|
||||
.map((g) => g as TccButton);
|
||||
}
|
||||
bind(g: TccButton): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.on('mousedown', this.onMouseDown, this);
|
||||
g.on('mouseup', this.onMouseUp, this);
|
||||
g.on('mouseout', this.onMouseOut, this);
|
||||
}
|
||||
|
||||
unbind(g: TccButton): void {
|
||||
g.eventMode = 'none';
|
||||
g.off('mousedown', this.onMouseDown, this);
|
||||
g.on('mouseup', this.onMouseUp, this);
|
||||
g.on('mouseout', this.onMouseOut, this);
|
||||
}
|
||||
onMouseOut(e: FederatedMouseEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const tccButton = target.getGraphic() as TccButton;
|
||||
if (tccButton.states.down && tccButton.datas.isSelfReset) {
|
||||
tccButton.states.down = false;
|
||||
tccButton.doRepaint();
|
||||
}
|
||||
}
|
||||
onMouseDown(e: FederatedMouseEvent) {
|
||||
const simulationId = useLineStore().simulationId;
|
||||
const mapId = useLineStore().mapId;
|
||||
const tccId = useTccStore().tccId;
|
||||
const target = e.target as DisplayObject;
|
||||
const tccButton = target.getGraphic() as TccButton;
|
||||
if (!simulationId || !mapId) {
|
||||
return;
|
||||
}
|
||||
console.log('按钮按下');
|
||||
}
|
||||
onMouseUp(e: FederatedMouseEvent) {
|
||||
const simulationId = useLineStore().simulationId;
|
||||
const mapId = useLineStore().mapId;
|
||||
const tccId = useTccStore().tccId;
|
||||
const target = e.target as DisplayObject;
|
||||
const tccButton = target.getGraphic() as TccButton;
|
||||
if (!simulationId || !mapId || !tccButton.datas.isSelfReset) {
|
||||
return;
|
||||
}
|
||||
console.log('按钮弹起');
|
||||
}
|
||||
}
|
59
src/drawApp/graphics/TccTextContentInteraction.ts
Normal file
59
src/drawApp/graphics/TccTextContentInteraction.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import {
|
||||
ITextContentData,
|
||||
TextContent,
|
||||
} from 'src/graphics/textContent/TextContent';
|
||||
import { tccGraphicData } from 'src/protos/tccGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
|
||||
export class TccTextData extends GraphicDataBase implements ITextContentData {
|
||||
constructor(data?: tccGraphicData.TccText) {
|
||||
let tccText;
|
||||
if (data) {
|
||||
tccText = data;
|
||||
} else {
|
||||
tccText = new tccGraphicData.TccText({
|
||||
common: GraphicDataBase.defaultCommonInfo(TextContent.Type),
|
||||
});
|
||||
}
|
||||
super(tccText);
|
||||
}
|
||||
|
||||
public get data(): tccGraphicData.TccText {
|
||||
return this.getData<tccGraphicData.TccText>();
|
||||
}
|
||||
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get content(): string {
|
||||
return this.data.content;
|
||||
}
|
||||
set content(v: string) {
|
||||
this.data.content = v;
|
||||
}
|
||||
get color(): string {
|
||||
return this.data.color;
|
||||
}
|
||||
set color(v: string) {
|
||||
this.data.color = v;
|
||||
}
|
||||
get fontSize(): number {
|
||||
return this.data.fontSize;
|
||||
}
|
||||
set fontSize(v: number) {
|
||||
this.data.fontSize = v;
|
||||
}
|
||||
clone(): TccTextData {
|
||||
return new TccTextData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: TccTextData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: TccTextData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
204
src/drawApp/tccApp.ts
Normal file
204
src/drawApp/tccApp.ts
Normal file
@ -0,0 +1,204 @@
|
||||
import { fromUint8Array, toUint8Array } from 'js-base64';
|
||||
import {
|
||||
CombinationKey,
|
||||
IDrawApp,
|
||||
IGraphicStorage,
|
||||
KeyListener,
|
||||
newDrawApp,
|
||||
GraphicData,
|
||||
ContextMenu,
|
||||
MenuItemOptions,
|
||||
} from 'jl-graphic';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { tccGraphicData } from 'src/protos/tccGraphics';
|
||||
import { saveDraft, getDraft } from 'src/api/DraftApi';
|
||||
import { useTccDrawStore } from 'src/stores/tcc-draw-store';
|
||||
import { successNotify, errorNotify } from '../utils/CommonNotify';
|
||||
import { toStorageTransform } from './graphics/GraphicDataBase';
|
||||
import { Dialog } from 'quasar';
|
||||
import { checkMapData } from 'src/api/Simulation';
|
||||
import { TccButtonData, TccButtonState } from './graphics/TccButtonInteraction';
|
||||
import { TccButtonDraw } from 'src/graphics/tccButton/TccButtonDrawAssistant';
|
||||
import { TccButton, TccButtonTemplate } from 'src/graphics/tccButton/TccButton';
|
||||
import {
|
||||
TextContent,
|
||||
TextContentTemplate,
|
||||
} from 'src/graphics/textContent/TextContent';
|
||||
import { TccTextData } from './graphics/TccTextContentInteraction';
|
||||
import { TextContentDraw } from 'src/graphics/textContent/TextContentDrawAssistant';
|
||||
|
||||
const UndoOptions: MenuItemOptions = {
|
||||
name: '撤销',
|
||||
};
|
||||
const RedoOptions: MenuItemOptions = {
|
||||
name: '重做',
|
||||
};
|
||||
const SelectAllOptions: MenuItemOptions = {
|
||||
name: '全选',
|
||||
};
|
||||
|
||||
export const DefaultCanvasMenu = new ContextMenu({
|
||||
name: '绘制-画布菜单',
|
||||
groups: [
|
||||
{
|
||||
items: [UndoOptions, RedoOptions],
|
||||
},
|
||||
{
|
||||
items: [SelectAllOptions],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let drawApp: IDrawApp | null = null;
|
||||
|
||||
export function getTccDrawApp(): IDrawApp | null {
|
||||
return drawApp;
|
||||
}
|
||||
|
||||
export function destroyTccDrawApp(): void {
|
||||
if (drawApp) {
|
||||
drawApp.destroy();
|
||||
drawApp = null;
|
||||
}
|
||||
}
|
||||
|
||||
export function initTccDrawApp(): IDrawApp {
|
||||
drawApp = newDrawApp({
|
||||
dataLoader: loadTccDrawDatas,
|
||||
});
|
||||
const app = drawApp;
|
||||
//根据草稿图类型加载绘图工具
|
||||
new TccButtonDraw(
|
||||
app,
|
||||
new TccButtonTemplate(new TccButtonData(), new TccButtonState())
|
||||
);
|
||||
new TextContentDraw(app, new TextContentTemplate(new TccTextData()));
|
||||
|
||||
// 画布右键菜单
|
||||
app.registerMenu(DefaultCanvasMenu);
|
||||
app.canvas.on('_rightclick', (e) => {
|
||||
if (app.drawing) return;
|
||||
UndoOptions.disabled = !app.opRecord.hasUndo;
|
||||
RedoOptions.disabled = !app.opRecord.hasRedo;
|
||||
|
||||
UndoOptions.handler = () => {
|
||||
app.opRecord.undo();
|
||||
};
|
||||
RedoOptions.handler = () => {
|
||||
app.opRecord.redo();
|
||||
};
|
||||
SelectAllOptions.handler = () => {
|
||||
app.selectAllGraphics();
|
||||
};
|
||||
DefaultCanvasMenu.open(e.global);
|
||||
});
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyS',
|
||||
global: true,
|
||||
combinations: [CombinationKey.Ctrl],
|
||||
onPress: () => {
|
||||
saveTccDrawToServer(app);
|
||||
},
|
||||
})
|
||||
);
|
||||
return drawApp;
|
||||
}
|
||||
|
||||
export function checkTccDataToServer(app: IDrawApp) {
|
||||
const base64 = saveTccDrawDatas(app);
|
||||
checkMapData({ mapProto: base64 })
|
||||
.then((res) => {
|
||||
if (res.data.success) {
|
||||
successNotify('校验数据成功!');
|
||||
} else {
|
||||
let message = '';
|
||||
res.data.errors.forEach((err: string) => {
|
||||
message += `<div>${err};<div>`;
|
||||
});
|
||||
Dialog.create({
|
||||
title: '校验失败',
|
||||
message: message,
|
||||
html: true,
|
||||
persistent: true,
|
||||
ok: {
|
||||
ali: 'center',
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
errorNotify(err.message, err);
|
||||
});
|
||||
}
|
||||
|
||||
export function saveTccDrawToServer(app: IDrawApp) {
|
||||
const base64 = saveTccDrawDatas(app);
|
||||
const tccDrawStore = useTccDrawStore();
|
||||
const id = tccDrawStore.draftId;
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
saveDraft(id as number, { proto: base64 })
|
||||
.then(() => {
|
||||
successNotify('保存数据成功!');
|
||||
})
|
||||
.catch((err) => {
|
||||
errorNotify(err.message, err);
|
||||
});
|
||||
}
|
||||
|
||||
export function saveTccDrawDatas(app: IDrawApp) {
|
||||
const storage = new tccGraphicData.TccGraphicStorage();
|
||||
const canvasData = app.canvas.saveData();
|
||||
storage.canvas = new graphicData.Canvas({
|
||||
width: canvasData.width,
|
||||
height: canvasData.height,
|
||||
backgroundColor: canvasData.backgroundColor,
|
||||
viewportTransform: toStorageTransform(canvasData.viewportTransform),
|
||||
});
|
||||
const graphics = app.queryStore.getAllGraphics();
|
||||
graphics.forEach((g) => {
|
||||
if (TccButton.Type === g.type) {
|
||||
const tccButtonData = (g as TccButton).saveData();
|
||||
storage.tccButtons.push((tccButtonData as TccButtonData).data);
|
||||
} else if (TextContent.Type === g.type) {
|
||||
const tccTextData = (g as TextContent).saveData();
|
||||
storage.tccTexts.push((tccTextData as TccTextData).data);
|
||||
}
|
||||
});
|
||||
const base64 = fromUint8Array(storage.serialize());
|
||||
console.log('保存数据', storage);
|
||||
return base64;
|
||||
}
|
||||
|
||||
export async function loadTccDrawDatas(): Promise<IGraphicStorage> {
|
||||
// console.log('加载数据', base64);
|
||||
const tccDrawStore = useTccDrawStore();
|
||||
const id = tccDrawStore.draftId;
|
||||
if (!id) {
|
||||
throw new Error('获取数据异常:为获取到草稿地图ID');
|
||||
}
|
||||
const { proto: base64 } = await getDraft(id);
|
||||
if (base64) {
|
||||
const storage = tccGraphicData.TccGraphicStorage.deserialize(
|
||||
toUint8Array(base64)
|
||||
);
|
||||
// app.updateCanvas(storage.canvas);
|
||||
const datas: GraphicData[] = [];
|
||||
storage.tccButtons.forEach((tccButton) => {
|
||||
datas.push(new TccButtonData(tccButton));
|
||||
});
|
||||
storage.tccTexts.forEach((tccText) => {
|
||||
datas.push(new TccTextData(tccText));
|
||||
});
|
||||
return {
|
||||
canvasProperty: storage.canvas,
|
||||
datas: datas,
|
||||
};
|
||||
} else {
|
||||
return Promise.resolve({
|
||||
datas: [],
|
||||
});
|
||||
}
|
||||
}
|
94
src/drawApp/tccScene.ts
Normal file
94
src/drawApp/tccScene.ts
Normal file
@ -0,0 +1,94 @@
|
||||
import {
|
||||
GraphicData,
|
||||
GraphicState,
|
||||
IGraphicApp,
|
||||
IGraphicScene,
|
||||
IGraphicStorage,
|
||||
} from 'jl-graphic';
|
||||
import { getPublishMapInfoByName } from 'src/api/PublishApi';
|
||||
import { useTccStore } from 'src/stores/tcc-store';
|
||||
import { toUint8Array } from 'js-base64';
|
||||
import { useLineStore } from 'src/stores/line-store';
|
||||
import { state } from 'src/protos/device_state';
|
||||
import { TccButtonData, TccButtonOperateInteraction, TccButtonState } from './graphics/TccButtonInteraction';
|
||||
import { tccGraphicData } from 'src/protos/tccGraphics';
|
||||
import { TccButtonTemplate } from 'src/graphics/tccButton/TccButton';
|
||||
|
||||
|
||||
export function initTccScene(lineApp: IGraphicApp, sceneName: string) {
|
||||
const tccScene = lineApp.initScene(sceneName, {
|
||||
dataLoader: loadTccDatas,
|
||||
mouseToolOptions: {
|
||||
boxSelect: false,
|
||||
viewportDrag: false,
|
||||
wheelZoom: false,
|
||||
},
|
||||
});
|
||||
const graphicTemplate = [
|
||||
new TccButtonTemplate(new TccButtonData(), new TccButtonState()),
|
||||
];
|
||||
TccButtonOperateInteraction.init(tccScene);
|
||||
tccScene.registerGraphicTemplates(...graphicTemplate);
|
||||
tccScene.on('postdataloaded', () => {
|
||||
handleSubscribe(tccScene);
|
||||
});
|
||||
tccScene.setOptions({
|
||||
mouseToolOptions: {
|
||||
boxSelect: false,
|
||||
viewportDrag: false,
|
||||
wheelZoom: false,
|
||||
},
|
||||
});
|
||||
return tccScene;
|
||||
}
|
||||
|
||||
function handleSubscribe(tccScene: IGraphicScene) {
|
||||
const lineStore = useLineStore();
|
||||
const tccStore = useTccStore();
|
||||
const simulationId = lineStore.simulationId;
|
||||
const mapId = lineStore.mapId;
|
||||
const tccId = tccStore.tccId;
|
||||
const app = tccScene;
|
||||
app.subscribe({
|
||||
destination: `/rtsts/simulation/${simulationId}/tcc/${mapId}/${tccId}`,
|
||||
messageConverter: (message: Uint8Array) => {
|
||||
// console.log('收到消息', message);
|
||||
const states: GraphicState[] = [];
|
||||
const storage = state.PushedDevicesStatus.deserialize(message);
|
||||
if (storage.all) {
|
||||
// storage.allStatus.buttonState.forEach((item) => {
|
||||
// if (item.id) {
|
||||
// states.push(new TccButtonState(item));
|
||||
// }
|
||||
// });
|
||||
}
|
||||
// console.log(states, 'states');
|
||||
return states;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function loadTccDatas(): Promise<IGraphicStorage> {
|
||||
const tccStore = useTccStore();
|
||||
const { proto: base64 } = await getPublishMapInfoByName({
|
||||
name: tccStore.tccMapCode,
|
||||
detail: true,
|
||||
});
|
||||
if (base64) {
|
||||
const storage = tccGraphicData.TccGraphicStorage.deserialize(
|
||||
toUint8Array(base64)
|
||||
);
|
||||
const datas: GraphicData[] = [];
|
||||
storage.tccButtons.forEach((tccButton) => {
|
||||
datas.push(new TccButtonData(tccButton));
|
||||
});
|
||||
return Promise.resolve({
|
||||
canvasProperty: storage.canvas,
|
||||
datas: datas,
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve({
|
||||
datas: [],
|
||||
});
|
||||
}
|
||||
}
|
104
src/graphics/tccButton/TccButton.ts
Normal file
104
src/graphics/tccButton/TccButton.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import {
|
||||
GraphicData,
|
||||
GraphicState,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
} from 'jl-graphic';
|
||||
import Tcc_Button_Assets from './tcc-button-spritesheet.png';
|
||||
import Tcc_Button_JSON from './tcc-button-data.json';
|
||||
|
||||
import { Assets, Sprite, Spritesheet, Texture } from 'pixi.js';
|
||||
import { tccGraphicData } from 'src/protos/tccGraphics';
|
||||
|
||||
interface TccButtonTextures {
|
||||
redBtn: Texture;
|
||||
greenBtn: Texture;
|
||||
redBtnPress: Texture;
|
||||
greenBtnPress: Texture;
|
||||
}
|
||||
|
||||
export interface ITccButtonData extends GraphicData {
|
||||
get code(): string;
|
||||
set code(v: string);
|
||||
get buttonColor(): tccGraphicData.TccElementColor;
|
||||
set buttonColor(v: tccGraphicData.TccElementColor);
|
||||
get isSelfReset(): boolean;
|
||||
set isSelfReset(v: boolean);
|
||||
}
|
||||
|
||||
export interface ITccButtonState extends GraphicState {
|
||||
get code(): string;
|
||||
set code(v: string);
|
||||
get down(): boolean;
|
||||
set down(v: boolean);
|
||||
}
|
||||
|
||||
export class TccButton extends JlGraphic {
|
||||
static Type = 'TccButton';
|
||||
_tccButton: Sprite;
|
||||
tccButtonTextures: TccButtonTextures;
|
||||
__state = 0;
|
||||
|
||||
constructor(tccButtonTextures: TccButtonTextures) {
|
||||
super(TccButton.Type);
|
||||
this.tccButtonTextures = tccButtonTextures;
|
||||
this._tccButton = new Sprite();
|
||||
this._tccButton.texture = this.tccButtonTextures.redBtn;
|
||||
this._tccButton.anchor.set(0.5);
|
||||
this.addChild(this._tccButton);
|
||||
}
|
||||
get code(): string {
|
||||
return this.datas.code;
|
||||
}
|
||||
get datas(): ITccButtonData {
|
||||
return this.getDatas<ITccButtonData>();
|
||||
}
|
||||
get states(): ITccButtonState {
|
||||
return this.getStates<ITccButtonState>();
|
||||
}
|
||||
doRepaint(): void {
|
||||
this._tccButton.rotation = 0;
|
||||
if (this.datas.buttonColor === tccGraphicData.TccElementColor.green) {
|
||||
if (this.states.down) {
|
||||
this._tccButton.texture = this.tccButtonTextures.greenBtnPress;
|
||||
} else {
|
||||
this._tccButton.texture = this.tccButtonTextures.greenBtn;
|
||||
}
|
||||
} else {
|
||||
if (this.states.down) {
|
||||
this._tccButton.texture = this.tccButtonTextures.redBtnPress;
|
||||
} else {
|
||||
this._tccButton.texture = this.tccButtonTextures.redBtn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class TccButtonTemplate extends JlGraphicTemplate<TccButton> {
|
||||
tccButtonTextures?: TccButtonTextures;
|
||||
constructor(dataTemplate: ITccButtonData, stateTemplate: ITccButtonState) {
|
||||
super(TccButton.Type, { dataTemplate, stateTemplate });
|
||||
this.loadAssets();
|
||||
}
|
||||
new(): TccButton {
|
||||
if (this.tccButtonTextures) {
|
||||
const g = new TccButton(this.tccButtonTextures);
|
||||
g.loadData(this.datas);
|
||||
g.loadState(this.states);
|
||||
return g;
|
||||
}
|
||||
throw new Error('资源未加载/加载失败');
|
||||
}
|
||||
async loadAssets(): Promise<TccButtonTextures> {
|
||||
const texture = await Assets.load(Tcc_Button_Assets);
|
||||
const tccButtonSheet = new Spritesheet(texture, Tcc_Button_JSON);
|
||||
const result = await tccButtonSheet.parse();
|
||||
this.tccButtonTextures = {
|
||||
redBtn: result['red-btn.png'],
|
||||
greenBtn: result['green-btn.png'],
|
||||
redBtnPress: result['red-btn-press.png'],
|
||||
greenBtnPress: result['green-btn-press.png'],
|
||||
};
|
||||
return this.tccButtonTextures as TccButtonTextures;
|
||||
}
|
||||
}
|
122
src/graphics/tccButton/TccButtonDrawAssistant.ts
Normal file
122
src/graphics/tccButton/TccButtonDrawAssistant.ts
Normal file
@ -0,0 +1,122 @@
|
||||
import { DisplayObject, FederatedMouseEvent, Point } from 'pixi.js';
|
||||
import {
|
||||
AbsorbableLine,
|
||||
AbsorbablePosition,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
GraphicTransformEvent,
|
||||
IDrawApp,
|
||||
JlGraphic,
|
||||
} from 'jl-graphic';
|
||||
import { ITccButtonData, TccButton, TccButtonTemplate } from './TccButton';
|
||||
|
||||
export class TccButtonDraw extends GraphicDrawAssistant<
|
||||
TccButtonTemplate,
|
||||
ITccButtonData
|
||||
> {
|
||||
_tccButton: TccButton | null = null;
|
||||
constructor(app: IDrawApp, template: TccButtonTemplate) {
|
||||
super(
|
||||
app,
|
||||
template,
|
||||
'svguse:../drawIcon.svg#icon-psl-button',
|
||||
'紧急制动按钮'
|
||||
);
|
||||
TccButtonInteraction.init(app);
|
||||
}
|
||||
|
||||
bind(): void {
|
||||
super.bind();
|
||||
if (!this._tccButton) {
|
||||
this._tccButton = this.graphicTemplate.new();
|
||||
this.container.addChild(this._tccButton);
|
||||
}
|
||||
}
|
||||
|
||||
public get tccButton(): TccButton {
|
||||
if (!this._tccButton) {
|
||||
this._tccButton = this.graphicTemplate.new();
|
||||
this.container.addChild(this._tccButton);
|
||||
}
|
||||
return this._tccButton;
|
||||
}
|
||||
|
||||
redraw(cp: Point): void {
|
||||
this.tccButton.position.copyFrom(cp);
|
||||
}
|
||||
onLeftUp(e: FederatedMouseEvent): void {
|
||||
this.tccButton.position.copyFrom(this.toCanvasCoordinates(e.global));
|
||||
this.createAndStore(true);
|
||||
}
|
||||
prepareData(data: ITccButtonData): boolean {
|
||||
data.transform = this.tccButton.saveTransform();
|
||||
return true;
|
||||
}
|
||||
onEsc(): void {
|
||||
this.finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建吸附线
|
||||
* @param tccButton
|
||||
*/
|
||||
function buildAbsorbablePositions(tccButton: TccButton): AbsorbablePosition[] {
|
||||
const aps: AbsorbablePosition[] = [];
|
||||
const tccButtons = tccButton.queryStore.queryByType<TccButton>(
|
||||
TccButton.Type
|
||||
);
|
||||
const canvas = tccButton.getCanvas();
|
||||
tccButtons.forEach((item) => {
|
||||
if (item.id === tccButton.id) {
|
||||
return;
|
||||
}
|
||||
const ala = new AbsorbableLine(
|
||||
new Point(item.x, 0),
|
||||
new Point(item.x, canvas.height)
|
||||
);
|
||||
const alb = new AbsorbableLine(
|
||||
new Point(0, item.y),
|
||||
new Point(canvas.width, item.y)
|
||||
);
|
||||
aps.push(ala);
|
||||
aps.push(alb);
|
||||
});
|
||||
|
||||
return aps;
|
||||
}
|
||||
|
||||
export class TccButtonInteraction extends GraphicInteractionPlugin<TccButton> {
|
||||
static Name = 'tcc_light_transform';
|
||||
constructor(app: IDrawApp) {
|
||||
super(TccButtonInteraction.Name, app);
|
||||
}
|
||||
static init(app: IDrawApp) {
|
||||
return new TccButtonInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): TccButton[] | undefined {
|
||||
return grahpics
|
||||
.filter((g) => g.type === TccButton.Type)
|
||||
.map((g) => g as TccButton);
|
||||
}
|
||||
bind(g: TccButton): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.scalable = true;
|
||||
g.rotatable = true;
|
||||
g.on('transformstart', this.transformstart, this);
|
||||
}
|
||||
unbind(g: TccButton): void {
|
||||
g.eventMode = 'none';
|
||||
g.scalable = false;
|
||||
g.rotatable = false;
|
||||
g.off('transformstart', this.transformstart, this);
|
||||
}
|
||||
transformstart(e: GraphicTransformEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const tccButton = target.getGraphic() as TccButton;
|
||||
tccButton.getGraphicApp().setOptions({
|
||||
absorbablePositions: buildAbsorbablePositions(tccButton),
|
||||
});
|
||||
}
|
||||
}
|
45
src/graphics/tccButton/tcc-button-data.json
Normal file
45
src/graphics/tccButton/tcc-button-data.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"frames": {
|
||||
"green-btn.png": {
|
||||
"frame": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"anchor": { "x": 0.5, "y": 0.5 }
|
||||
},
|
||||
"red-btn.png": {
|
||||
"frame": { "x": 64, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"anchor": { "x": 0.5, "y": 0.5 }
|
||||
},
|
||||
"green-btn-press.png": {
|
||||
"frame": { "x": 128, "y": 0, "w": 59, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 59, "h": 64 },
|
||||
"sourceSize": { "w": 59, "h": 64 },
|
||||
"anchor": { "x": 0.5, "y": 0.5 }
|
||||
},
|
||||
"red-btn-press.png": {
|
||||
"frame": { "x": 187, "y": 0, "w": 59, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 59, "h": 64 },
|
||||
"sourceSize": { "w": 59, "h": 64 },
|
||||
"anchor": { "x": 0.5, "y": 0.5 }
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"app": "https://www.codeandweb.com/texturepacker",
|
||||
"version": "1.1",
|
||||
"image": "psl-button.png",
|
||||
"format": "RGBA8888",
|
||||
"size": { "w": 246, "h": 64 },
|
||||
"scale": "1",
|
||||
"smartupdate": "$TexturePacker:SmartUpdate:e7620bd2d73cc0b3e2deea9704e7eefc:f129a1d9e4b9ba57720b3861c22b155b:eb2d421f7759984b7713aa4aa5354134$"
|
||||
}
|
||||
}
|
BIN
src/graphics/tccButton/tcc-button-spritesheet.png
Normal file
BIN
src/graphics/tccButton/tcc-button-spritesheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
295
src/layouts/TrainControlCabDrawLayout.vue
Normal file
295
src/layouts/TrainControlCabDrawLayout.vue
Normal file
@ -0,0 +1,295 @@
|
||||
<template>
|
||||
<q-layout view="hHh LpR fFf">
|
||||
<q-header reveal class="bg-primary text-white">
|
||||
<q-toolbar>
|
||||
<q-toolbar-title class="q-gutter-sm">
|
||||
<q-btn color="accent" label="功能菜单">
|
||||
<q-menu>
|
||||
<q-list style="min-width: 100px">
|
||||
<q-item clickable v-close-popup @click="saveAllDrawDatas">
|
||||
<q-item-section>保存</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="saveAsDialog = true">
|
||||
<q-item-section>另存为</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="handleCheckData">
|
||||
<q-item-section>数据校验</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="buildRelations">
|
||||
<q-item-section>一键关联</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
<q-btn-toggle
|
||||
v-model="selectUtil"
|
||||
color="brown"
|
||||
text-color="white"
|
||||
toggle-color="orange"
|
||||
toggle-text-color="black"
|
||||
:options="utilsOption"
|
||||
@update:model-value="drawSelect"
|
||||
>
|
||||
<template
|
||||
v-for="(ctl, idx) in utilsOption"
|
||||
:key="idx"
|
||||
v-slot:[ctl.value]
|
||||
>
|
||||
<q-tooltip>{{ ctl.tip }}</q-tooltip>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</q-toolbar-title>
|
||||
<q-btn square color="purple" style="margin-right: 10px" icon="search">
|
||||
<q-popup-edit
|
||||
ref="popupEdit"
|
||||
v-model="searchId"
|
||||
:cover="false"
|
||||
:offset="[0, 10]"
|
||||
v-slot="scope"
|
||||
>
|
||||
<q-input
|
||||
color="accent"
|
||||
v-model="scope.value"
|
||||
label="设备Id"
|
||||
dense
|
||||
autofocus
|
||||
@keyup.enter="scope.set"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="search" color="accent" />
|
||||
</template>
|
||||
</q-input>
|
||||
</q-popup-edit>
|
||||
</q-btn>
|
||||
<q-btn color="info" label="返回" @click="backConfirm" />
|
||||
<q-btn dense flat round icon="menu" @click="toggleRightDrawer" />
|
||||
</q-toolbar>
|
||||
<q-resize-observer @resize="onHeaderResize" />
|
||||
</q-header>
|
||||
|
||||
<q-drawer show-if-above bordered v-model="rightDrawerOpen" side="right">
|
||||
<q-resize-observer @resize="onRightResize" />
|
||||
<tcc-draw-properties></tcc-draw-properties>
|
||||
</q-drawer>
|
||||
|
||||
<q-page-container style="overflow: hidden">
|
||||
<div id="draw-app-container"></div>
|
||||
</q-page-container>
|
||||
|
||||
<q-dialog
|
||||
v-model="saveAsDialog"
|
||||
persistent
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
>
|
||||
<q-card style="width: 300px">
|
||||
<q-card-section>
|
||||
<div class="text-h6">另存为</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section>
|
||||
<q-input
|
||||
outlined
|
||||
label="草稿名称"
|
||||
v-model="saveAsName"
|
||||
:rules="[(val) => val.trim() != '' || '草稿名称不能为空']"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn color="primary" label="提交" @click="saveAs(saveAsName)" />
|
||||
<q-btn label="取消" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import TccDrawProperties from 'src/components/draw-app/TccDrawProperties.vue';
|
||||
import {
|
||||
getTccDrawApp,
|
||||
saveTccDrawDatas,
|
||||
saveTccDrawToServer,
|
||||
checkTccDataToServer,
|
||||
} from 'src/drawApp/tccApp';
|
||||
import { IDrawApp } from 'jl-graphic';
|
||||
import { useTccDrawStore } from 'src/stores/tcc-draw-store';
|
||||
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { errorNotify, successNotify } from 'src/utils/CommonNotify';
|
||||
import { saveAsDraft } from 'src/api/DraftApi';
|
||||
import { ApiError } from 'src/boot/axios';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { TccButton } from 'src/graphics/tccButton/TccButton';
|
||||
import { TextContent } from 'src/graphics/textContent/TextContent';
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const searchId = ref(0);
|
||||
|
||||
const tccDrawStore = useTccDrawStore();
|
||||
|
||||
watch(
|
||||
() => tccDrawStore.drawMode,
|
||||
(drawMode) => {
|
||||
if (!drawMode) {
|
||||
selectUtil.value = '';
|
||||
}
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => searchId.value,
|
||||
() => {
|
||||
try {
|
||||
if (searchId.value) {
|
||||
const device = tccDrawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryById(searchId.value);
|
||||
tccDrawStore.getDrawApp().makeGraphicCenterShow(device);
|
||||
tccDrawStore.getDrawApp().updateSelected(device);
|
||||
}
|
||||
} catch (err) {
|
||||
$q.notify({
|
||||
type: 'negative',
|
||||
message: `未查找到id为【${searchId.value}】的设备`,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const leftDrawerOpen = ref(false);
|
||||
const rightDrawerOpen = ref(false);
|
||||
function toggleRightDrawer() {
|
||||
rightDrawerOpen.value = !rightDrawerOpen.value;
|
||||
onResize();
|
||||
}
|
||||
|
||||
//工具栏所用
|
||||
const selectUtil = ref();
|
||||
const utilsOption: ControlItem[] = reactive([]);
|
||||
const drawSelect = (item: string) => {
|
||||
getTccDrawApp()?.interactionPlugin(item).resume();
|
||||
};
|
||||
class ControlItem {
|
||||
value: string;
|
||||
slot: string;
|
||||
icon: string;
|
||||
tip: string;
|
||||
show = true;
|
||||
|
||||
constructor(value: string, icon: string, tip: string, show?: boolean) {
|
||||
this.value = value;
|
||||
this.slot = value;
|
||||
this.icon = icon;
|
||||
this.tip = tip;
|
||||
if (show != undefined) {
|
||||
this.show = show;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log('绘制应用layout mounted');
|
||||
const dom = document.getElementById('draw-app-container');
|
||||
if (dom) {
|
||||
tccDrawStore.setDraftId(+route.params.id as number);
|
||||
const drawApp = tccDrawStore.initDrawApp();
|
||||
drawApp.bindDom(dom);
|
||||
drawApp.reload();
|
||||
onResize();
|
||||
} else {
|
||||
tccDrawStore.setDraftId(null);
|
||||
}
|
||||
|
||||
const drawAssistantsTypes = [TccButton.Type, TextContent.Type];
|
||||
drawAssistantsTypes.forEach((type) => {
|
||||
const drawAssistant = getTccDrawApp()?.getDrawAssistant(type);
|
||||
if (drawAssistant) {
|
||||
utilsOption.push(
|
||||
new ControlItem(
|
||||
drawAssistant.name,
|
||||
drawAssistant.icon,
|
||||
drawAssistant.description || drawAssistant.name
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const canvasWidth = ref(0);
|
||||
const canvasHeight = ref(0);
|
||||
const headerHeight = ref(0);
|
||||
const leftWidth = ref(0);
|
||||
const rightWidth = ref(0);
|
||||
|
||||
function onHeaderResize(size: { height: number; width: number }) {
|
||||
headerHeight.value = size.height;
|
||||
onResize();
|
||||
}
|
||||
|
||||
function onRightResize(size: { height: number; width: number }) {
|
||||
rightWidth.value = size.width;
|
||||
onResize();
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
const clientWidth = document.documentElement.clientWidth;
|
||||
const clientHeight = document.documentElement.clientHeight;
|
||||
canvasWidth.value =
|
||||
clientWidth -
|
||||
(leftDrawerOpen.value ? leftWidth.value : 0) -
|
||||
(rightDrawerOpen.value ? rightWidth.value : 0);
|
||||
canvasHeight.value = clientHeight - headerHeight.value;
|
||||
const dom = document.getElementById('draw-app-container');
|
||||
if (dom) {
|
||||
dom.style.width = canvasWidth.value + 'px';
|
||||
dom.style.height = canvasHeight.value + 'px';
|
||||
}
|
||||
}
|
||||
function saveAllDrawDatas() {
|
||||
const drawApp = getTccDrawApp();
|
||||
saveTccDrawToServer(drawApp as IDrawApp);
|
||||
}
|
||||
|
||||
function handleCheckData() {
|
||||
const drawApp = getTccDrawApp();
|
||||
checkTccDataToServer(drawApp as IDrawApp);
|
||||
}
|
||||
|
||||
function buildRelations() {
|
||||
const app = getTccDrawApp();
|
||||
app?.detectRelations();
|
||||
}
|
||||
|
||||
function backConfirm() {
|
||||
router.go(-1);
|
||||
}
|
||||
|
||||
const saveAsDialog = ref(false);
|
||||
const saveAsName = ref('');
|
||||
|
||||
async function saveAs(name: string) {
|
||||
try {
|
||||
const drawApp = getTccDrawApp();
|
||||
const base64 = saveTccDrawDatas(drawApp as IDrawApp);
|
||||
const record = await saveAsDraft(+route.params.id as number, {
|
||||
name,
|
||||
proto: base64,
|
||||
});
|
||||
if (record) {
|
||||
router.replace(`/painting/${record.id}/${record.type}`);
|
||||
}
|
||||
successNotify('另存为成功');
|
||||
saveAsDialog.value = false;
|
||||
} catch (e) {
|
||||
const error = e as ApiError;
|
||||
errorNotify(error.title, e);
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
tccDrawStore.destroy();
|
||||
});
|
||||
</script>
|
@ -386,6 +386,7 @@ const pictureTypeList: { label: string; value: PictureType }[] = [
|
||||
{ label: 'PSL', value: PictureType.Psl },
|
||||
{ label: '继电器柜布置图', value: PictureType.RelayCabinetLayout },
|
||||
{ label: 'IBP盘', value: PictureType.IBP },
|
||||
{ label: '列车驾驶台', value: PictureType.TrainControlCab },
|
||||
];
|
||||
const categoryId = ref('');
|
||||
const pictureType = ref(PictureType.StationLayout);
|
||||
@ -416,6 +417,8 @@ function goToPath(row: DraftItem) {
|
||||
path = `/pslPainting/${row.id}`;
|
||||
} else if (row.type === PictureType.IBP) {
|
||||
path = `/ibpPainting/${row.id}`;
|
||||
} else if (row.type === PictureType.TrainControlCab) {
|
||||
path = `/trainControlCabPainting/${row.id}`;
|
||||
}
|
||||
router.push({ path: path });
|
||||
}
|
||||
|
@ -9,5 +9,6 @@ export enum PictureType {
|
||||
Psl = 1,
|
||||
RelayCabinetLayout = 2,
|
||||
IBP = 3,
|
||||
TrainData = 4
|
||||
TrainData = 4,
|
||||
TrainControlCab = 5
|
||||
}
|
||||
|
430
src/protos/tccGraphics.ts
Normal file
430
src/protos/tccGraphics.ts
Normal file
@ -0,0 +1,430 @@
|
||||
/**
|
||||
* Generated by the protoc-gen-ts. DO NOT EDIT!
|
||||
* compiler version: 4.23.1
|
||||
* source: tccGraphics.proto
|
||||
* git: https://github.com/thesayyn/protoc-gen-ts */
|
||||
import * as dependency_1 from "./stationLayoutGraphics";
|
||||
import * as pb_1 from "google-protobuf";
|
||||
export namespace tccGraphicData {
|
||||
export enum TccElementColor {
|
||||
green = 0,
|
||||
red = 1
|
||||
}
|
||||
export class TccGraphicStorage extends pb_1.Message {
|
||||
#one_of_decls: number[][] = [];
|
||||
constructor(data?: any[] | {
|
||||
canvas?: dependency_1.graphicData.Canvas;
|
||||
tccButtons?: TccButton[];
|
||||
tccTexts?: TccText[];
|
||||
}) {
|
||||
super();
|
||||
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3], this.#one_of_decls);
|
||||
if (!Array.isArray(data) && typeof data == "object") {
|
||||
if ("canvas" in data && data.canvas != undefined) {
|
||||
this.canvas = data.canvas;
|
||||
}
|
||||
if ("tccButtons" in data && data.tccButtons != undefined) {
|
||||
this.tccButtons = data.tccButtons;
|
||||
}
|
||||
if ("tccTexts" in data && data.tccTexts != undefined) {
|
||||
this.tccTexts = data.tccTexts;
|
||||
}
|
||||
}
|
||||
}
|
||||
get canvas() {
|
||||
return pb_1.Message.getWrapperField(this, dependency_1.graphicData.Canvas, 1) as dependency_1.graphicData.Canvas;
|
||||
}
|
||||
set canvas(value: dependency_1.graphicData.Canvas) {
|
||||
pb_1.Message.setWrapperField(this, 1, value);
|
||||
}
|
||||
get has_canvas() {
|
||||
return pb_1.Message.getField(this, 1) != null;
|
||||
}
|
||||
get tccButtons() {
|
||||
return pb_1.Message.getRepeatedWrapperField(this, TccButton, 2) as TccButton[];
|
||||
}
|
||||
set tccButtons(value: TccButton[]) {
|
||||
pb_1.Message.setRepeatedWrapperField(this, 2, value);
|
||||
}
|
||||
get tccTexts() {
|
||||
return pb_1.Message.getRepeatedWrapperField(this, TccText, 3) as TccText[];
|
||||
}
|
||||
set tccTexts(value: TccText[]) {
|
||||
pb_1.Message.setRepeatedWrapperField(this, 3, value);
|
||||
}
|
||||
static fromObject(data: {
|
||||
canvas?: ReturnType<typeof dependency_1.graphicData.Canvas.prototype.toObject>;
|
||||
tccButtons?: ReturnType<typeof TccButton.prototype.toObject>[];
|
||||
tccTexts?: ReturnType<typeof TccText.prototype.toObject>[];
|
||||
}): TccGraphicStorage {
|
||||
const message = new TccGraphicStorage({});
|
||||
if (data.canvas != null) {
|
||||
message.canvas = dependency_1.graphicData.Canvas.fromObject(data.canvas);
|
||||
}
|
||||
if (data.tccButtons != null) {
|
||||
message.tccButtons = data.tccButtons.map(item => TccButton.fromObject(item));
|
||||
}
|
||||
if (data.tccTexts != null) {
|
||||
message.tccTexts = data.tccTexts.map(item => TccText.fromObject(item));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
toObject() {
|
||||
const data: {
|
||||
canvas?: ReturnType<typeof dependency_1.graphicData.Canvas.prototype.toObject>;
|
||||
tccButtons?: ReturnType<typeof TccButton.prototype.toObject>[];
|
||||
tccTexts?: ReturnType<typeof TccText.prototype.toObject>[];
|
||||
} = {};
|
||||
if (this.canvas != null) {
|
||||
data.canvas = this.canvas.toObject();
|
||||
}
|
||||
if (this.tccButtons != null) {
|
||||
data.tccButtons = this.tccButtons.map((item: TccButton) => item.toObject());
|
||||
}
|
||||
if (this.tccTexts != null) {
|
||||
data.tccTexts = this.tccTexts.map((item: TccText) => item.toObject());
|
||||
}
|
||||
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.has_canvas)
|
||||
writer.writeMessage(1, this.canvas, () => this.canvas.serialize(writer));
|
||||
if (this.tccButtons.length)
|
||||
writer.writeRepeatedMessage(2, this.tccButtons, (item: TccButton) => item.serialize(writer));
|
||||
if (this.tccTexts.length)
|
||||
writer.writeRepeatedMessage(3, this.tccTexts, (item: TccText) => item.serialize(writer));
|
||||
if (!w)
|
||||
return writer.getResultBuffer();
|
||||
}
|
||||
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): TccGraphicStorage {
|
||||
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new TccGraphicStorage();
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup())
|
||||
break;
|
||||
switch (reader.getFieldNumber()) {
|
||||
case 1:
|
||||
reader.readMessage(message.canvas, () => message.canvas = dependency_1.graphicData.Canvas.deserialize(reader));
|
||||
break;
|
||||
case 2:
|
||||
reader.readMessage(message.tccButtons, () => pb_1.Message.addToRepeatedWrapperField(message, 2, TccButton.deserialize(reader), TccButton));
|
||||
break;
|
||||
case 3:
|
||||
reader.readMessage(message.tccTexts, () => pb_1.Message.addToRepeatedWrapperField(message, 3, TccText.deserialize(reader), TccText));
|
||||
break;
|
||||
default: reader.skipField();
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
serializeBinary(): Uint8Array {
|
||||
return this.serialize();
|
||||
}
|
||||
static deserializeBinary(bytes: Uint8Array): TccGraphicStorage {
|
||||
return TccGraphicStorage.deserialize(bytes);
|
||||
}
|
||||
}
|
||||
export class TccButton extends pb_1.Message {
|
||||
#one_of_decls: number[][] = [];
|
||||
constructor(data?: any[] | {
|
||||
common?: dependency_1.graphicData.CommonInfo;
|
||||
code?: string;
|
||||
buttonColor?: TccElementColor;
|
||||
isSelfReset?: 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 ("common" in data && data.common != undefined) {
|
||||
this.common = data.common;
|
||||
}
|
||||
if ("code" in data && data.code != undefined) {
|
||||
this.code = data.code;
|
||||
}
|
||||
if ("buttonColor" in data && data.buttonColor != undefined) {
|
||||
this.buttonColor = data.buttonColor;
|
||||
}
|
||||
if ("isSelfReset" in data && data.isSelfReset != undefined) {
|
||||
this.isSelfReset = data.isSelfReset;
|
||||
}
|
||||
}
|
||||
}
|
||||
get common() {
|
||||
return pb_1.Message.getWrapperField(this, dependency_1.graphicData.CommonInfo, 1) as dependency_1.graphicData.CommonInfo;
|
||||
}
|
||||
set common(value: dependency_1.graphicData.CommonInfo) {
|
||||
pb_1.Message.setWrapperField(this, 1, value);
|
||||
}
|
||||
get has_common() {
|
||||
return pb_1.Message.getField(this, 1) != null;
|
||||
}
|
||||
get code() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 2, "") as string;
|
||||
}
|
||||
set code(value: string) {
|
||||
pb_1.Message.setField(this, 2, value);
|
||||
}
|
||||
get buttonColor() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 3, TccElementColor.green) as TccElementColor;
|
||||
}
|
||||
set buttonColor(value: TccElementColor) {
|
||||
pb_1.Message.setField(this, 3, value);
|
||||
}
|
||||
get isSelfReset() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 4, false) as boolean;
|
||||
}
|
||||
set isSelfReset(value: boolean) {
|
||||
pb_1.Message.setField(this, 4, value);
|
||||
}
|
||||
static fromObject(data: {
|
||||
common?: ReturnType<typeof dependency_1.graphicData.CommonInfo.prototype.toObject>;
|
||||
code?: string;
|
||||
buttonColor?: TccElementColor;
|
||||
isSelfReset?: boolean;
|
||||
}): TccButton {
|
||||
const message = new TccButton({});
|
||||
if (data.common != null) {
|
||||
message.common = dependency_1.graphicData.CommonInfo.fromObject(data.common);
|
||||
}
|
||||
if (data.code != null) {
|
||||
message.code = data.code;
|
||||
}
|
||||
if (data.buttonColor != null) {
|
||||
message.buttonColor = data.buttonColor;
|
||||
}
|
||||
if (data.isSelfReset != null) {
|
||||
message.isSelfReset = data.isSelfReset;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
toObject() {
|
||||
const data: {
|
||||
common?: ReturnType<typeof dependency_1.graphicData.CommonInfo.prototype.toObject>;
|
||||
code?: string;
|
||||
buttonColor?: TccElementColor;
|
||||
isSelfReset?: boolean;
|
||||
} = {};
|
||||
if (this.common != null) {
|
||||
data.common = this.common.toObject();
|
||||
}
|
||||
if (this.code != null) {
|
||||
data.code = this.code;
|
||||
}
|
||||
if (this.buttonColor != null) {
|
||||
data.buttonColor = this.buttonColor;
|
||||
}
|
||||
if (this.isSelfReset != null) {
|
||||
data.isSelfReset = this.isSelfReset;
|
||||
}
|
||||
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.has_common)
|
||||
writer.writeMessage(1, this.common, () => this.common.serialize(writer));
|
||||
if (this.code.length)
|
||||
writer.writeString(2, this.code);
|
||||
if (this.buttonColor != TccElementColor.green)
|
||||
writer.writeEnum(3, this.buttonColor);
|
||||
if (this.isSelfReset != false)
|
||||
writer.writeBool(4, this.isSelfReset);
|
||||
if (!w)
|
||||
return writer.getResultBuffer();
|
||||
}
|
||||
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): TccButton {
|
||||
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new TccButton();
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup())
|
||||
break;
|
||||
switch (reader.getFieldNumber()) {
|
||||
case 1:
|
||||
reader.readMessage(message.common, () => message.common = dependency_1.graphicData.CommonInfo.deserialize(reader));
|
||||
break;
|
||||
case 2:
|
||||
message.code = reader.readString();
|
||||
break;
|
||||
case 3:
|
||||
message.buttonColor = reader.readEnum();
|
||||
break;
|
||||
case 4:
|
||||
message.isSelfReset = reader.readBool();
|
||||
break;
|
||||
default: reader.skipField();
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
serializeBinary(): Uint8Array {
|
||||
return this.serialize();
|
||||
}
|
||||
static deserializeBinary(bytes: Uint8Array): TccButton {
|
||||
return TccButton.deserialize(bytes);
|
||||
}
|
||||
}
|
||||
export class TccText extends pb_1.Message {
|
||||
#one_of_decls: number[][] = [];
|
||||
constructor(data?: any[] | {
|
||||
common?: dependency_1.graphicData.CommonInfo;
|
||||
code?: string;
|
||||
content?: string;
|
||||
color?: string;
|
||||
fontSize?: number;
|
||||
}) {
|
||||
super();
|
||||
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
|
||||
if (!Array.isArray(data) && typeof data == "object") {
|
||||
if ("common" in data && data.common != undefined) {
|
||||
this.common = data.common;
|
||||
}
|
||||
if ("code" in data && data.code != undefined) {
|
||||
this.code = data.code;
|
||||
}
|
||||
if ("content" in data && data.content != undefined) {
|
||||
this.content = data.content;
|
||||
}
|
||||
if ("color" in data && data.color != undefined) {
|
||||
this.color = data.color;
|
||||
}
|
||||
if ("fontSize" in data && data.fontSize != undefined) {
|
||||
this.fontSize = data.fontSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
get common() {
|
||||
return pb_1.Message.getWrapperField(this, dependency_1.graphicData.CommonInfo, 1) as dependency_1.graphicData.CommonInfo;
|
||||
}
|
||||
set common(value: dependency_1.graphicData.CommonInfo) {
|
||||
pb_1.Message.setWrapperField(this, 1, value);
|
||||
}
|
||||
get has_common() {
|
||||
return pb_1.Message.getField(this, 1) != null;
|
||||
}
|
||||
get code() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 2, "") as string;
|
||||
}
|
||||
set code(value: string) {
|
||||
pb_1.Message.setField(this, 2, value);
|
||||
}
|
||||
get content() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 3, "") as string;
|
||||
}
|
||||
set content(value: string) {
|
||||
pb_1.Message.setField(this, 3, value);
|
||||
}
|
||||
get color() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 4, "") as string;
|
||||
}
|
||||
set color(value: string) {
|
||||
pb_1.Message.setField(this, 4, value);
|
||||
}
|
||||
get fontSize() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 5, 0) as number;
|
||||
}
|
||||
set fontSize(value: number) {
|
||||
pb_1.Message.setField(this, 5, value);
|
||||
}
|
||||
static fromObject(data: {
|
||||
common?: ReturnType<typeof dependency_1.graphicData.CommonInfo.prototype.toObject>;
|
||||
code?: string;
|
||||
content?: string;
|
||||
color?: string;
|
||||
fontSize?: number;
|
||||
}): TccText {
|
||||
const message = new TccText({});
|
||||
if (data.common != null) {
|
||||
message.common = dependency_1.graphicData.CommonInfo.fromObject(data.common);
|
||||
}
|
||||
if (data.code != null) {
|
||||
message.code = data.code;
|
||||
}
|
||||
if (data.content != null) {
|
||||
message.content = data.content;
|
||||
}
|
||||
if (data.color != null) {
|
||||
message.color = data.color;
|
||||
}
|
||||
if (data.fontSize != null) {
|
||||
message.fontSize = data.fontSize;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
toObject() {
|
||||
const data: {
|
||||
common?: ReturnType<typeof dependency_1.graphicData.CommonInfo.prototype.toObject>;
|
||||
code?: string;
|
||||
content?: string;
|
||||
color?: string;
|
||||
fontSize?: number;
|
||||
} = {};
|
||||
if (this.common != null) {
|
||||
data.common = this.common.toObject();
|
||||
}
|
||||
if (this.code != null) {
|
||||
data.code = this.code;
|
||||
}
|
||||
if (this.content != null) {
|
||||
data.content = this.content;
|
||||
}
|
||||
if (this.color != null) {
|
||||
data.color = this.color;
|
||||
}
|
||||
if (this.fontSize != null) {
|
||||
data.fontSize = this.fontSize;
|
||||
}
|
||||
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.has_common)
|
||||
writer.writeMessage(1, this.common, () => this.common.serialize(writer));
|
||||
if (this.code.length)
|
||||
writer.writeString(2, this.code);
|
||||
if (this.content.length)
|
||||
writer.writeString(3, this.content);
|
||||
if (this.color.length)
|
||||
writer.writeString(4, this.color);
|
||||
if (this.fontSize != 0)
|
||||
writer.writeInt32(5, this.fontSize);
|
||||
if (!w)
|
||||
return writer.getResultBuffer();
|
||||
}
|
||||
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): TccText {
|
||||
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new TccText();
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup())
|
||||
break;
|
||||
switch (reader.getFieldNumber()) {
|
||||
case 1:
|
||||
reader.readMessage(message.common, () => message.common = dependency_1.graphicData.CommonInfo.deserialize(reader));
|
||||
break;
|
||||
case 2:
|
||||
message.code = reader.readString();
|
||||
break;
|
||||
case 3:
|
||||
message.content = reader.readString();
|
||||
break;
|
||||
case 4:
|
||||
message.color = reader.readString();
|
||||
break;
|
||||
case 5:
|
||||
message.fontSize = reader.readInt32();
|
||||
break;
|
||||
default: reader.skipField();
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
serializeBinary(): Uint8Array {
|
||||
return this.serialize();
|
||||
}
|
||||
static deserializeBinary(bytes: Uint8Array): TccText {
|
||||
return TccText.deserialize(bytes);
|
||||
}
|
||||
}
|
||||
}
|
@ -189,6 +189,14 @@ export const asyncRoutes: RouteRecordRaw[] = [
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/trainControlCabPainting/:id',
|
||||
name: 'trainControlCabPainting',
|
||||
component: () => import('src/layouts/TrainControlCabDrawLayout.vue'),
|
||||
meta: {
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/linemap',
|
||||
name: 'linemap',
|
||||
|
91
src/stores/tcc-draw-store.ts
Normal file
91
src/stores/tcc-draw-store.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import {
|
||||
destroyTccDrawApp,
|
||||
getTccDrawApp,
|
||||
initTccDrawApp,
|
||||
} from 'src/drawApp/tccApp';
|
||||
import { DrawAssistant, IJlCanvas, IDrawApp, JlGraphic } from 'jl-graphic';
|
||||
|
||||
export const useTccDrawStore = defineStore('tccDraw', {
|
||||
state: () => ({
|
||||
drawAssistant: null as DrawAssistant | null,
|
||||
selectedGraphics: null as JlGraphic[] | null,
|
||||
draftId: null as number | null,
|
||||
draftType: 'Tcc',
|
||||
oneClickType: ''
|
||||
}),
|
||||
getters: {
|
||||
drawMode: (state) => state.drawAssistant != null,
|
||||
drawGraphicType: (state) => state.drawAssistant?.type,
|
||||
drawGraphicName: (state) => state.drawAssistant?.description,
|
||||
drawGraphicTemplate: (state) => state.drawAssistant?.graphicTemplate,
|
||||
|
||||
selectedGraphicType: (state) => {
|
||||
if (state.selectedGraphics) {
|
||||
if (state.selectedGraphics.length === 1) {
|
||||
return state.selectedGraphics[0].type;
|
||||
}
|
||||
}
|
||||
},
|
||||
selectedObjName: (state) => {
|
||||
if (state.selectedGraphics) {
|
||||
if (state.selectedGraphics.length == 0) {
|
||||
return '画布';
|
||||
} else if (state.selectedGraphics.length == 1) {
|
||||
return state.selectedGraphics[0].type;
|
||||
}
|
||||
return '多选';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
selectedGraphic: (state) => {
|
||||
if (state.selectedGraphics) {
|
||||
if (state.selectedGraphics.length === 1) {
|
||||
return state.selectedGraphics[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
getDrawApp(): IDrawApp {
|
||||
const app = getTccDrawApp();
|
||||
if (app == null) {
|
||||
throw new Error('未初始化app');
|
||||
}
|
||||
return app;
|
||||
},
|
||||
getJlCanvas(): IJlCanvas {
|
||||
return this.getDrawApp().canvas;
|
||||
},
|
||||
initDrawApp() {
|
||||
const app = initTccDrawApp();
|
||||
app.on('interaction-plugin-resume', (plugin) => {
|
||||
if (plugin.isAppPlugin()) {
|
||||
if (Object.hasOwn(plugin, '__GraphicDrawAssistant')) {
|
||||
this.drawAssistant = plugin as DrawAssistant;
|
||||
} else {
|
||||
this.drawAssistant = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
app.on('graphicselectedchange', () => {
|
||||
this.selectedGraphics = app.selectedGraphics;
|
||||
});
|
||||
this.selectedGraphics = [];
|
||||
return app;
|
||||
},
|
||||
destroy() {
|
||||
// console.log('绘制状态清空,绘制应用销毁');
|
||||
this.drawAssistant = null;
|
||||
this.selectedGraphics = null;
|
||||
destroyTccDrawApp();
|
||||
},
|
||||
setDraftId(id: number | null) {
|
||||
this.draftId = id;
|
||||
},
|
||||
setDraftType(type: string) {
|
||||
this.draftType = type;
|
||||
},
|
||||
},
|
||||
});
|
33
src/stores/tcc-store.ts
Normal file
33
src/stores/tcc-store.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { initTccScene } from 'src/drawApp/tccScene';
|
||||
import { getLineApp } from 'src/drawApp/lineApp';
|
||||
|
||||
export const useTccStore = defineStore('tcc', {
|
||||
state: () => ({
|
||||
tccMapCode: '',
|
||||
tccId: 0,
|
||||
isTccDialogOpen: false,
|
||||
}),
|
||||
actions: {
|
||||
getTccScene() {
|
||||
const lineApp = getLineApp();
|
||||
if (!lineApp) throw Error('未初始化app');
|
||||
try {
|
||||
return lineApp.getScene('tcc');
|
||||
} catch (error) {
|
||||
const tccScene = initTccScene(lineApp, 'tcc');
|
||||
return tccScene;
|
||||
}
|
||||
},
|
||||
setTccParam(tccId: number, tccMapCode: string) {
|
||||
this.tccId = tccId;
|
||||
this.tccMapCode = tccMapCode;
|
||||
this.isTccDialogOpen = true;
|
||||
},
|
||||
clearTccParam() {
|
||||
this.tccId = 0;
|
||||
this.tccMapCode = '';
|
||||
this.isTccDialogOpen = false;
|
||||
},
|
||||
},
|
||||
});
|
Loading…
Reference in New Issue
Block a user