Merge branch 'master' of git.code.tencent.com:xian-ncc-da/xian-ncc-da-client
This commit is contained in:
commit
855b8a3eb8
@ -1 +1 @@
|
||||
Subproject commit 7789ad9dc210c3c5c61bbb7e5b507b518f0abcf5
|
||||
Subproject commit fe0ba85437c2601451e3fed4769441907cf8addf
|
18
public/drawIcon.svg
Normal file
18
public/drawIcon.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<symbol id="icon-curve" viewBox="0 0 1280 1024">
|
||||
<path
|
||||
d="M1280 614.4c0-32-32-64-64-64-38.4 0-64 32-64 64 0 44.8-12.8 172.8-70.4 236.8-32 32-70.4 44.8-121.6 44.8-89.6 0-153.6-243.2-204.8-416-64-249.6-128-480-294.4-480C224 0 115.2 364.8 44.8 601.6c-12.8 51.2-25.6 96-38.4 121.6-12.8 32 6.4 70.4 38.4 83.2 32 12.8 70.4-6.4 83.2-38.4 12.8-32 25.6-76.8 44.8-134.4C217.6 460.8 320 128 460.8 128 531.2 128 595.2 358.4 640 512c70.4 249.6 140.8 512 326.4 512 83.2 0 153.6-25.6 204.8-83.2 115.2-121.6 108.8-320 108.8-326.4z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-fans" viewBox="0 0 1024 1024">
|
||||
<path d="M947.303 517.937c-16.16-18.18-39.391-29.289-63.629-29.289h-240.377c-6.061-30.299-21.21-56.56-44.441-75.748l120.189-208.058c12.119-21.21 14.141-46.46 6.061-69.69s-25.249-40.398-47.47-49.49c-53.529-21.21-109.077-31.31-166.649-31.31s-113.118 10.1-166.649 31.31c-22.22 9.090-39.391 27.27-47.47 49.49-8.079 23.23-6.061 48.481 6.061 69.69l120.189 208.058c-22.22 19.188-38.379 46.46-44.441 75.748h-239.367c-24.238 0-47.47 11.109-63.629 29.289-16.16 18.18-22.22 42.42-19.188 66.659 9.090 56.56 27.27 110.087 56.56 159.578 28.278 49.49 65.65 92.917 110.087 128.269 15.149 12.119 33.329 18.18 51.51 18.18 5.050 0 10.1 0 15.149-1.009 24.238-4.041 44.441-19.188 56.56-40.398l120.189-208.058c6.061 2.020 12.119 4.041 19.188 5.050v289.867c0 14.141 11.109 25.249 25.249 25.249s25.249-11.109 25.249-25.249v-289.867c6.061-1.009 13.13-3.028 19.188-5.050l120.189 208.058c12.119 21.21 33.329 35.349 56.56 40.398 5.050 1.009 10.1 1.009 15.149 1.009 18.18 0 36.357-6.061 51.51-18.18 44.441-35.349 81.81-78.778 110.087-128.269 28.278-49.49 47.47-104.027 56.56-159.578 5.050-23.23-2.020-47.47-18.18-66.659zM303.942 823.961c-5.050 8.079-13.13 14.141-22.22 16.16s-18.18-1.009-26.259-6.061c-39.391-31.31-72.72-70.7-97.969-114.127-25.249-44.441-42.42-91.908-50.499-142.407-1.009-9.090 1.009-18.18 7.069-25.249s15.149-11.109 25.249-11.109h241.387c6.061 30.299 21.21 56.56 44.441 75.748l-121.197 207.047zM347.373 179.591c-5.050-8.079-6.061-18.18-3.028-27.27 3.028-9.090 10.1-16.16 18.18-19.188 47.47-18.18 96.958-28.278 148.468-28.278s100.998 9.090 148.468 28.278c9.090 3.028 15.149 10.1 18.18 19.188 3.028 9.090 2.020 19.188-3.028 27.27l-118.167 208.058c-14.141-5.050-28.278-7.069-44.441-7.069s-30.299 3.028-44.441 7.069l-120.189-208.058zM512 598.735c-46.46 0-83.829-37.37-83.829-83.829s37.37-83.829 83.829-83.829 83.829 37.37 83.829 83.829-37.37 83.829-83.829 83.829zM917.006 576.516c-8.079 50.499-24.238 97.969-50.499 142.407-25.249 44.441-58.579 82.818-97.969 114.127-7.069 6.061-16.16 8.079-26.259 6.061-9.090-2.020-18.18-8.079-22.22-16.16l-120.189-207.047c22.22-19.188 38.379-46.46 44.441-75.748h240.377c10.1 0 19.188 4.041 25.249 11.109 5.050 7.069 8.079 16.16 7.069 25.249z" p-id="12530"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-platform" viewBox="0 0 1024 1024">
|
||||
<path d="M199.68 564.906667L170.666667 721.92h250.88L392.533333 564.906667H199.68zM179.2 512h235.52c11.946667 0 23.893333 8.533333 25.6 22.186667l39.253333 209.92c1.706667 6.826667 0 15.36-5.12 22.186666s-11.946667 10.24-20.48 10.24H139.946667c-8.533333 0-15.36-3.413333-20.48-10.24-5.12-6.826667-6.826667-13.653333-5.12-22.186666L153.6 534.186667c1.706667-13.653333 11.946667-22.186667 25.6-22.186667z m411.306667 209.92h250.88l-29.013334-157.013333H619.52l-29.013333 157.013333zM597.333333 512h235.52c11.946667 0 23.893333 8.533333 25.6 22.186667l39.253334 209.92c1.706667 6.826667 0 15.36-5.12 22.186666s-11.946667 10.24-20.48 10.24H558.08c-8.533333 0-15.36-3.413333-20.48-10.24-5.12-6.826667-6.826667-13.653333-5.12-22.186666l39.253333-209.92c3.413333-13.653333 13.653333-22.186667 25.6-22.186667z m-216.746666-52.906667H631.466667l-29.013334-157.013333H409.6l-29.013333 157.013333z m6.826666-209.92h235.52c11.946667 0 23.893333 8.533333 25.6 22.186667l39.253334 209.92c1.706667 6.826667 0 15.36-5.12 22.186667s-11.946667 10.24-20.48 10.24H348.16c-8.533333 0-15.36-3.413333-20.48-10.24-5.12-6.826667-6.826667-13.653333-5.12-22.186667l39.253333-209.92c3.413333-11.946667 13.653333-22.186667 25.6-22.186667z m0 0" p-id="9166"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-station" viewBox="0 0 1024 1024">
|
||||
<path d="M890.3 390.6l-309.1-299c-38.3-37-100.5-37.1-138.9-0.3l-308.5 296c-9.2 8.9-14.4 20.9-14.4 33.4v456c0 52.2 43.9 84.4 98.1 84.4h147.2c54.2 0 98.1-32.3 98.1-84.4v-47.2c0-26.1 22-47.2 49.1-47.2s49.1 21.2 49.1 47.2v47.2c0 52.2 43.9 84.4 98.1 84.4h147.2c54.2 0 98.1-32.3 98.1-84.4V424c0.2-12.5-5-24.5-14.1-33.4z m-83.9 438.9c0 26.1-22 37.2-49.1 37.2h-49.1c-27.1 0-49.1-11.1-49.1-37.2v-47.2c0-52.2-43.9-104.5-98.1-104.5h-98.1c-54.2 0-98.1 52.3-98.1 104.5v47.2c0 26.1-22 37.2-49.1 37.2h-49.1c-27.1 0-49.1-11.1-49.1-37.2V448.7c0-6.3 2.6-12.3 7.2-16.7l252.1-242.6c19.2-18.5 50.3-18.5 69.4 0L799.3 433c4.6 4.4 7.2 10.4 7.2 16.7v379.8z" p-id="20574"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-signal" viewBox="0 0 1024 1024">
|
||||
<path d="M63.33 895.64V127.99h64v767.65z" fill="#fdfafa" p-id="24054"></path><path d="M750 365.57a146.25 146.25 0 1 1-103.36 42.83A145.29 145.29 0 0 1 750 365.57m0-64c-116.12 0-210.25 94.13-210.25 210.25S633.93 722.06 750 722.06s210.3-94.13 210.3-210.25S866.16 301.57 750 301.57z" fill="#fdfafa" p-id="24055"></path><path d="M336.94 365.57a146 146 0 1 1-103.27 42.78 145.09 145.09 0 0 1 103.27-42.78m0-64c-116 0-210 94-210 210s94 210 210 210 210-94 210-210-94-210-210-210z" fill="#fdfafa" p-id="24056"></path>
|
||||
</symbol>
|
||||
</svg>
|
After Width: | Height: | Size: 5.3 KiB |
@ -47,6 +47,7 @@ module.exports = configure(function (/* ctx */) {
|
||||
|
||||
'roboto-font', // optional, you are not bound to it
|
||||
'material-icons', // optional, you are not bound to it
|
||||
'material-symbols-outlined',
|
||||
],
|
||||
|
||||
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
|
||||
@ -71,7 +72,7 @@ module.exports = configure(function (/* ctx */) {
|
||||
// minify: false,
|
||||
// polyfillModulePreload: true,
|
||||
// distDir
|
||||
distDir: `dist/${BasePath}`,
|
||||
// distDir: `dist/${BasePath}`,
|
||||
|
||||
// extendViteConf (viteConf) {},
|
||||
// viteVuePluginOptions: {},
|
||||
|
@ -6,9 +6,10 @@ const DraftUriBase = '/api/drafting';
|
||||
interface Item {
|
||||
id: number;
|
||||
name: string;
|
||||
proto: Array<string>;
|
||||
proto: string;
|
||||
createdAt: string;
|
||||
updateAt: string;
|
||||
creatorId?: number;
|
||||
}
|
||||
|
||||
export class PagingQueryParams extends PageQueryDto {
|
||||
@ -42,7 +43,7 @@ export function createDraft(draftData: { name: string }) {
|
||||
* 删除草稿
|
||||
* @param id 草稿id
|
||||
*/
|
||||
export function deleteDraft(id: string) {
|
||||
export function deleteDraft(id: number) {
|
||||
return api.delete(`${DraftUriBase}/${id}`);
|
||||
}
|
||||
|
||||
@ -63,6 +64,21 @@ export function publishDraft(data: {
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export function getDraft(id: string) {
|
||||
return api.get(`${DraftUriBase}/${id}`);
|
||||
export async function getDraft(id: number): Promise<Item> {
|
||||
const response = await api.get(`${DraftUriBase}/${id}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存草稿数据
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
export function saveDraft(
|
||||
id: number,
|
||||
data: {
|
||||
proto: string;
|
||||
}
|
||||
) {
|
||||
return api.put(`${DraftUriBase}/${id}`, data);
|
||||
}
|
||||
|
@ -57,6 +57,9 @@
|
||||
<iscs-fan-property
|
||||
v-else-if="drawStore.selectedGraphicType === IscsFan.Type"
|
||||
></iscs-fan-property>
|
||||
<signal-property
|
||||
v-else-if="drawStore.selectedGraphicType === Signal.Type"
|
||||
></signal-property>
|
||||
</q-card-section>
|
||||
</template>
|
||||
</q-card>
|
||||
@ -75,6 +78,7 @@ import PlatformProperty from './properties/PlatformProperty.vue';
|
||||
import StationProperty from './properties/StationProperty.vue';
|
||||
import TrainProperty from './properties/TrainProperty.vue';
|
||||
import IscsFanProperty from './properties/IscsFanProperty.vue';
|
||||
import SignalProperty from './properties/SignalProperty.vue';
|
||||
import { Link } from 'src/graphics/link/Link';
|
||||
import { Rect } from 'src/graphics/rect/Rect';
|
||||
import { Platform } from 'src/graphics/platform/Platform';
|
||||
@ -82,6 +86,7 @@ import { Station } from 'src/graphics/station/Station';
|
||||
import { Train } from 'src/graphics/train/Train';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { IscsFan } from 'src/graphics/iscs-fan/IscsFan';
|
||||
import { Signal } from 'src/graphics/signal/Signal';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
</script>
|
||||
|
69
src/components/draw-app/properties/SignalProperty.vue
Normal file
69
src/components/draw-app/properties/SignalProperty.vue
Normal file
@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<q-form>
|
||||
<q-input outlined readonly v-model="signalModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="signalModel.code"
|
||||
@blur="onUpdate"
|
||||
label="编号"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="signalDirection"
|
||||
:options="optionsDirection"
|
||||
label="方向"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SignalData } from 'src/drawApp/graphics/SignalInteraction';
|
||||
import { Signal } from 'src/graphics/signal/Signal';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const signalModel = reactive(new SignalData());
|
||||
const signalDirection = ref('向右');
|
||||
const optionsDirection = ['向左', '向右', '向上', '向下'];
|
||||
enum directionSelect {
|
||||
向左 = 'left',
|
||||
向右 = 'right',
|
||||
向上 = 'up',
|
||||
向下 = 'down',
|
||||
}
|
||||
enum directionMap {
|
||||
left = '向左',
|
||||
right = '向右',
|
||||
up = '向上',
|
||||
down = '向下',
|
||||
}
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Signal.Type) {
|
||||
signalModel.copyFrom(val.saveData() as SignalData);
|
||||
signalDirection.value = (directionMap as never)[signalModel.direction];
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const signal = drawStore.selectedGraphic as Signal;
|
||||
if (signal) {
|
||||
signalModel.copyFrom(signal.saveData());
|
||||
signalDirection.value = (directionMap as never)[signalModel.direction];
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
signalModel.direction = (directionSelect as never)[signalDirection.value];
|
||||
const signal = drawStore.selectedGraphic as Signal;
|
||||
if (signal) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(signal, signalModel);
|
||||
}
|
||||
}
|
||||
</script>
|
62
src/drawApp/graphics/SignalInteraction.ts
Normal file
62
src/drawApp/graphics/SignalInteraction.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { IPointData } from 'pixi.js';
|
||||
import { ISignalData } from 'src/graphics/signal/Signal';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
|
||||
export class SignalData extends GraphicDataBase implements ISignalData {
|
||||
constructor(data?: graphicData.Signal) {
|
||||
let signal;
|
||||
if (!data) {
|
||||
signal = new graphicData.Signal({
|
||||
common: GraphicDataBase.defaultCommonInfo(),
|
||||
});
|
||||
} else {
|
||||
signal = data;
|
||||
}
|
||||
super(signal);
|
||||
}
|
||||
|
||||
public get data(): graphicData.Signal {
|
||||
return this.getData<graphicData.Signal>();
|
||||
}
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get codeColor(): string {
|
||||
return this.data.codeColor;
|
||||
}
|
||||
set codeColor(v: string) {
|
||||
this.data.codeColor = v;
|
||||
}
|
||||
get codeFontSize(): number {
|
||||
return this.data.codeFontSize;
|
||||
}
|
||||
set codeFontSize(v: number) {
|
||||
this.data.codeFontSize = v;
|
||||
}
|
||||
get point(): IPointData {
|
||||
return this.data.point;
|
||||
}
|
||||
set point(point: IPointData) {
|
||||
this.data.point = new graphicData.Point({ x: point.x, y: point.y });
|
||||
}
|
||||
get direction(): string {
|
||||
return this.data.direction;
|
||||
}
|
||||
set direction(v: string) {
|
||||
this.data.direction = v;
|
||||
}
|
||||
clone(): SignalData {
|
||||
return new SignalData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: SignalData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: SignalData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ import { Station } from 'src/graphics/station/Station';
|
||||
import { Train } from 'src/graphics/train/Train';
|
||||
import { StationDraw } from 'src/graphics/station/StationDrawAssistant';
|
||||
import { TrainDraw } from 'src/graphics/train/TrainDrawAssistant';
|
||||
import { Signal } from 'src/graphics/signal/Signal';
|
||||
import { SignalDraw } from 'src/graphics/signal/SignalDrawAssistant';
|
||||
import {
|
||||
CombinationKey,
|
||||
GraphicApp,
|
||||
@ -28,10 +30,14 @@ import { RectData } from './graphics/RectInteraction';
|
||||
import { PlatformData } from './graphics/PlatformInteraction';
|
||||
import { StationData } from './graphics/StationInteraction';
|
||||
import { TrainData } from './graphics/TrainInteraction';
|
||||
import { SignalData } from './graphics/SignalInteraction';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { TurnoutDraw } from 'src/graphics/turnout/TurnoutDrawAssistant';
|
||||
import { TurnoutData } from './graphics/TurnoutInteraction';
|
||||
import { saveDraft, getDraft } from 'src/api/DraftApi';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { successNotify, errorNotify } from '../utils/CommonNotify';
|
||||
|
||||
export function fromStoragePoint(p: graphicData.Point): Point {
|
||||
return new Point(p.x, p.y);
|
||||
@ -103,23 +109,14 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
const app = drawApp;
|
||||
app.setOptions({
|
||||
drawAssistants: [
|
||||
new LinkDraw(app, () => {
|
||||
return new LinkData();
|
||||
}),
|
||||
new RectDraw(app, () => {
|
||||
return new RectData();
|
||||
}),
|
||||
new IscsFanDraw(app, () => {
|
||||
return new IscsFanData();
|
||||
}),
|
||||
new PlatformDraw(app, () => {
|
||||
return new PlatformData();
|
||||
}),
|
||||
new StationDraw(app, () => {
|
||||
return new StationData();
|
||||
}),
|
||||
new TrainDraw(app, () => {
|
||||
return new TrainData();
|
||||
new SignalDraw(app, () => {
|
||||
return new SignalData();
|
||||
}),
|
||||
new TurnoutDraw(app, () => {
|
||||
return new TurnoutData();
|
||||
@ -145,40 +142,6 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
DefaultCanvasMenu.open(e.global);
|
||||
});
|
||||
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyL',
|
||||
onPress: () => {
|
||||
app.interactionPlugin(Link.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyW',
|
||||
onPress: () => {
|
||||
console.log(app.interactionPlugin(Turnout.Type));
|
||||
app.interactionPlugin(Turnout.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyR',
|
||||
onPress: () => {
|
||||
app.interactionPlugin(Rect.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyF',
|
||||
onPress: () => {
|
||||
console.log(1);
|
||||
app.interactionPlugin(IscsFan.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyP',
|
||||
@ -187,6 +150,15 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyT',
|
||||
onPress: () => {
|
||||
console.log(app.interactionPlugin(Turnout.Type));
|
||||
app.interactionPlugin(Turnout.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyO',
|
||||
@ -197,21 +169,9 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyT',
|
||||
value: 'KeyH',
|
||||
onPress: () => {
|
||||
app.interactionPlugin(Train.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: '1',
|
||||
onPress: () => {
|
||||
app.queryStore.queryByType<IscsFan>(IscsFan.Type).forEach((fan) => {
|
||||
fan.__state = fan.__state + 1;
|
||||
fan.__state = fan.__state % 5;
|
||||
fan.repaint();
|
||||
});
|
||||
app.interactionPlugin(Signal.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
@ -228,7 +188,7 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
return drawApp;
|
||||
}
|
||||
|
||||
const StorageKey = 'graphic-storage';
|
||||
// const StorageKey = 'graphic-storage';
|
||||
export function saveDrawDatas(app: JlDrawApp) {
|
||||
const storage = new graphicData.RtssGraphicStorage();
|
||||
const canvasData = app.canvas.saveData();
|
||||
@ -259,17 +219,38 @@ export function saveDrawDatas(app: JlDrawApp) {
|
||||
} else if (Turnout.Type === g.type) {
|
||||
const turnoutData = (g as Turnout).saveData();
|
||||
storage.turnouts.push((turnoutData as TurnoutData).data);
|
||||
} else if (Signal.Type === g.type) {
|
||||
const signalData = (g as Signal).saveData();
|
||||
storage.signals.push((signalData as SignalData).data);
|
||||
}
|
||||
});
|
||||
const base64 = fromUint8Array(storage.serialize());
|
||||
console.log('保存数据', storage);
|
||||
localStorage.setItem(StorageKey, base64);
|
||||
// localStorage.setItem(StorageKey, base64);
|
||||
const drawStore = useDrawStore();
|
||||
const id = drawStore.draftId;
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
saveDraft(id as number, { proto: base64 })
|
||||
.then(() => {
|
||||
successNotify('保存数据成功!');
|
||||
})
|
||||
.catch((err) => {
|
||||
errorNotify('保存数据失败!', err.message);
|
||||
});
|
||||
}
|
||||
|
||||
export function loadDrawDatas(app: GraphicApp) {
|
||||
export async function loadDrawDatas(app: GraphicApp) {
|
||||
// localStorage.removeItem(StorageKey);
|
||||
const base64 = localStorage.getItem(StorageKey);
|
||||
// const base64 = localStorage.getItem(StorageKey);
|
||||
// console.log('加载数据', base64);
|
||||
const drawStore = useDrawStore();
|
||||
const id = drawStore.draftId;
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
const { proto: base64 } = await getDraft(id);
|
||||
if (base64) {
|
||||
const storage = graphicData.RtssGraphicStorage.deserialize(
|
||||
toUint8Array(base64)
|
||||
@ -298,6 +279,9 @@ export function loadDrawDatas(app: GraphicApp) {
|
||||
storage.turnouts.forEach((turnout) => {
|
||||
datas.push(new TurnoutData(turnout));
|
||||
});
|
||||
storage.signals.forEach((signal) => {
|
||||
datas.push(new SignalData(signal));
|
||||
});
|
||||
app.loadGraphic(datas);
|
||||
} else {
|
||||
app.loadGraphic([]);
|
||||
|
@ -15,7 +15,13 @@ export class IscsFanDraw extends GraphicDrawAssistant<
|
||||
|
||||
constructor(app: JlDrawApp, createData: () => IIscsFanData) {
|
||||
const template = new IscsFanTemplate();
|
||||
super(app, template, createData, IscsFan.Type, '风机');
|
||||
super(
|
||||
app,
|
||||
template,
|
||||
createData,
|
||||
'svguse:../drawIcon.svg#icon-fans',
|
||||
'风机'
|
||||
);
|
||||
IscsFanInteraction.init(app);
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ export class LinkDraw extends GraphicDrawAssistant<LinkTemplate, ILinkData> {
|
||||
});
|
||||
|
||||
constructor(app: JlDrawApp, createData: () => ILinkData) {
|
||||
super(app, new LinkTemplate(), createData, Link.Type, '轨道Link');
|
||||
super(app, new LinkTemplate(), createData, 'sym_o_horizontal_rule', '轨道Link');
|
||||
this.container.addChild(this.graphic);
|
||||
this.graphicTemplate.curve = true;
|
||||
|
||||
|
@ -32,7 +32,7 @@ export class PlatformDraw extends GraphicDrawAssistant<
|
||||
app,
|
||||
new PlatformTemplate(),
|
||||
createData,
|
||||
Platform.Type,
|
||||
'svguse:../drawIcon.svg#icon-platform',
|
||||
'站台Platform'
|
||||
);
|
||||
this.container.addChild(this.platformGraphic);
|
||||
@ -52,9 +52,6 @@ export class PlatformDraw extends GraphicDrawAssistant<
|
||||
this.platformGraphic.clear();
|
||||
this.doorGraphic.clear();
|
||||
}
|
||||
onRightClick(): void {
|
||||
this.createAndStore(true);
|
||||
}
|
||||
onLeftDown(e: FederatedPointerEvent): void {
|
||||
const { x, y } = this.toCanvasCoordinates(e.global);
|
||||
const p = new Point(x, y);
|
||||
|
@ -44,7 +44,7 @@ export class RectDraw extends GraphicDrawAssistant<RectTemplate, IRectData> {
|
||||
rectGraphic: Graphics = new Graphics();
|
||||
|
||||
constructor(app: JlDrawApp, createData: () => IRectData) {
|
||||
super(app, new RectTemplate(), createData, Rect.Type, '站台Rect');
|
||||
super(app, new RectTemplate(), createData, 'sym_o_square', '矩形Rect');
|
||||
this.container.addChild(this.rectGraphic);
|
||||
RectPointsEditPlugin.init(app);
|
||||
}
|
||||
@ -59,9 +59,6 @@ export class RectDraw extends GraphicDrawAssistant<RectTemplate, IRectData> {
|
||||
clearCache(): void {
|
||||
this.rectGraphic.clear();
|
||||
}
|
||||
onRightClick(): void {
|
||||
this.createAndStore(true);
|
||||
}
|
||||
onLeftDown(e: FederatedPointerEvent): void {
|
||||
const { x, y } = this.toCanvasCoordinates(e.global);
|
||||
const p = new Point(x, y);
|
||||
@ -159,7 +156,9 @@ function buildAbsorbablePositions(rect: Rect): AbsorbablePosition[] {
|
||||
return;
|
||||
}
|
||||
other.linePoints.forEach((point) => {
|
||||
const absorbablePoint = new AbsorbablePoint(point);
|
||||
const absorbablePoint = new AbsorbablePoint(
|
||||
other.localToCanvasPoint(point)
|
||||
);
|
||||
aps.push(absorbablePoint);
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,217 @@
|
||||
import { IPointData, Graphics, Color } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
VectorText,
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
export interface ISignalData extends GraphicData {
|
||||
get code(): string; // 编号
|
||||
set code(v: string);
|
||||
get codeColor(): string;
|
||||
set codeColor(v: string);
|
||||
get codeFontSize(): number;
|
||||
set codeFontSize(v: number);
|
||||
get point(): IPointData;
|
||||
set point(point: IPointData);
|
||||
get direction(): string;
|
||||
set direction(v: string);
|
||||
clone(): ISignalData;
|
||||
copyFrom(data: ISignalData): void;
|
||||
eq(other: ISignalData): boolean;
|
||||
}
|
||||
|
||||
//站台颜色
|
||||
export enum SignalColorEnum {
|
||||
lampPostColor = '0xc0c0c0',
|
||||
lampColor = '0xff0000',
|
||||
humanControlColor = '0xffff00',
|
||||
fleetModeColor = '0x00ff00',
|
||||
logicModeColor = '0x000000',
|
||||
}
|
||||
|
||||
const signalConsts = {
|
||||
verticalLampPostLength: 20,
|
||||
levelLampPostLength: 5,
|
||||
lineWidth: 3,
|
||||
lampRadius: 10,
|
||||
nameOffsetY: 20,
|
||||
humanControlPath: [-2, 0, -17, 10, -17, -10],
|
||||
logicModeLineWidth: 2,
|
||||
logicModeDistance: 7,
|
||||
fleetModePath: [2, -4, 22, -4, 22, -10, 35, 0, 22, 10, 22, 4, 2, 4],
|
||||
};
|
||||
export class Signal extends JlGraphic {
|
||||
static Type = 'signal';
|
||||
codeGraph: VectorText = new VectorText('');
|
||||
lampPost: Graphics = new Graphics();
|
||||
circularLamp: Graphics = new Graphics();
|
||||
humanControl: Graphics = new Graphics();
|
||||
fleetMode: Graphics = new Graphics();
|
||||
logicMode: Graphics = new Graphics();
|
||||
|
||||
constructor() {
|
||||
super(Signal.Type);
|
||||
this.addChild(this.codeGraph);
|
||||
this.addChild(this.lampPost);
|
||||
this.addChild(this.circularLamp);
|
||||
this.addChild(this.humanControl);
|
||||
this.addChild(this.fleetMode);
|
||||
this.addChild(this.logicMode);
|
||||
}
|
||||
|
||||
get datas(): ISignalData {
|
||||
return this.getDatas<ISignalData>();
|
||||
}
|
||||
doRepaint(): void {
|
||||
const codeGraph = this.codeGraph;
|
||||
this.lampPost.clear();
|
||||
this.lampPost.lineStyle(
|
||||
signalConsts.lineWidth,
|
||||
new Color(SignalColorEnum.lampPostColor)
|
||||
);
|
||||
this.lampPost.moveTo(0, -signalConsts.verticalLampPostLength / 2);
|
||||
this.lampPost.lineTo(0, signalConsts.verticalLampPostLength / 2);
|
||||
this.lampPost.moveTo(0, 0);
|
||||
this.lampPost.lineTo(signalConsts.levelLampPostLength, 0);
|
||||
this.circularLamp.beginFill(SignalColorEnum.lampColor, 1);
|
||||
this.circularLamp.drawCircle(
|
||||
signalConsts.levelLampPostLength + signalConsts.lampRadius,
|
||||
0,
|
||||
signalConsts.lampRadius
|
||||
);
|
||||
this.circularLamp.endFill();
|
||||
this.humanControl.beginFill(SignalColorEnum.humanControlColor, 1);
|
||||
this.humanControl.drawPolygon(signalConsts.humanControlPath);
|
||||
this.humanControl.endFill();
|
||||
this.fleetMode.beginFill(SignalColorEnum.fleetModeColor, 1);
|
||||
const fleetModePath: number[] = [];
|
||||
signalConsts.fleetModePath.forEach((item: number, index: number) => {
|
||||
if (!(index % 2)) {
|
||||
fleetModePath.push(
|
||||
item + signalConsts.levelLampPostLength + signalConsts.lampRadius * 2
|
||||
);
|
||||
} else {
|
||||
fleetModePath.push(item);
|
||||
}
|
||||
});
|
||||
this.fleetMode.drawPolygon(fleetModePath);
|
||||
this.fleetMode.endFill();
|
||||
this.logicMode.lineStyle(2, new Color(SignalColorEnum.logicModeColor));
|
||||
this.logicMode.moveTo(
|
||||
signalConsts.levelLampPostLength +
|
||||
signalConsts.lampRadius -
|
||||
signalConsts.logicModeDistance,
|
||||
signalConsts.logicModeDistance
|
||||
);
|
||||
this.logicMode.lineTo(
|
||||
signalConsts.levelLampPostLength +
|
||||
signalConsts.lampRadius +
|
||||
signalConsts.logicModeDistance,
|
||||
-signalConsts.logicModeDistance
|
||||
);
|
||||
this.logicMode.moveTo(
|
||||
signalConsts.levelLampPostLength +
|
||||
signalConsts.lampRadius -
|
||||
signalConsts.logicModeDistance,
|
||||
-signalConsts.logicModeDistance
|
||||
);
|
||||
this.logicMode.lineTo(
|
||||
signalConsts.levelLampPostLength +
|
||||
signalConsts.lampRadius +
|
||||
signalConsts.logicModeDistance,
|
||||
signalConsts.logicModeDistance
|
||||
);
|
||||
if (this.datas.code == '') {
|
||||
codeGraph.text = '信号机Signal';
|
||||
} else {
|
||||
codeGraph.text = this.datas.code;
|
||||
}
|
||||
codeGraph.style.fill = this.datas.codeColor;
|
||||
codeGraph.setVectorFontSize(this.datas.codeFontSize);
|
||||
codeGraph.anchor.set(0.5);
|
||||
codeGraph.style.fill = this.datas.codeColor;
|
||||
codeGraph.position.set(0, signalConsts.nameOffsetY);
|
||||
if (this.datas.direction === 'left') {
|
||||
this.lampPost.rotation = Math.PI;
|
||||
this.circularLamp.rotation = Math.PI;
|
||||
this.humanControl.rotation = Math.PI;
|
||||
this.fleetMode.rotation = Math.PI;
|
||||
this.logicMode.rotation = Math.PI;
|
||||
} else if (this.datas.direction === 'up') {
|
||||
this.lampPost.rotation = (Math.PI / 2) * 3;
|
||||
this.circularLamp.rotation = (Math.PI / 2) * 3;
|
||||
this.humanControl.rotation = (Math.PI / 2) * 3;
|
||||
this.fleetMode.rotation = (Math.PI / 2) * 3;
|
||||
this.logicMode.rotation = (Math.PI / 2) * 3;
|
||||
} else if (this.datas.direction === 'down') {
|
||||
this.lampPost.rotation = Math.PI / 2;
|
||||
this.circularLamp.rotation = Math.PI / 2;
|
||||
this.humanControl.rotation = Math.PI / 2;
|
||||
this.fleetMode.rotation = Math.PI / 2;
|
||||
this.logicMode.rotation = Math.PI / 2;
|
||||
} else {
|
||||
this.lampPost.rotation = 0;
|
||||
this.circularLamp.rotation = 0;
|
||||
this.humanControl.rotation = 0;
|
||||
this.fleetMode.rotation = 0;
|
||||
this.logicMode.rotation = 0;
|
||||
}
|
||||
|
||||
this.position.set(this.datas.point.x, this.datas.point.y);
|
||||
}
|
||||
}
|
||||
|
||||
export class SignalTemplate extends JlGraphicTemplate<Signal> {
|
||||
codeColor: string;
|
||||
codeFontSize: number;
|
||||
direction: string;
|
||||
verticalLampPostLength: number;
|
||||
levelLampPostLength: number;
|
||||
lineWidth: number;
|
||||
lampRadius: number;
|
||||
lampPostColor: string;
|
||||
lampColor: string;
|
||||
humanControlColor: string;
|
||||
fleetModeColor: string;
|
||||
logicModeColor: string;
|
||||
humanControlPath: number[];
|
||||
logicModeLineWidth: number;
|
||||
logicModeDistance: number;
|
||||
fleetModePath: number[];
|
||||
nameOffsetY: number;
|
||||
constructor() {
|
||||
super(Signal.Type);
|
||||
this.codeColor = '0xff0000';
|
||||
this.codeFontSize = 11;
|
||||
this.direction = 'right';
|
||||
this.verticalLampPostLength = signalConsts.verticalLampPostLength;
|
||||
this.levelLampPostLength = signalConsts.levelLampPostLength;
|
||||
this.lineWidth = signalConsts.lineWidth;
|
||||
this.lampRadius = signalConsts.lampRadius;
|
||||
this.lampPostColor = SignalColorEnum.lampPostColor;
|
||||
this.lampColor = SignalColorEnum.lampColor;
|
||||
this.humanControlColor = SignalColorEnum.humanControlColor;
|
||||
this.fleetModeColor = SignalColorEnum.fleetModeColor;
|
||||
this.logicModeColor = SignalColorEnum.logicModeColor;
|
||||
this.humanControlPath = signalConsts.humanControlPath;
|
||||
this.logicModeLineWidth = signalConsts.logicModeLineWidth;
|
||||
this.logicModeDistance = signalConsts.logicModeDistance;
|
||||
this.nameOffsetY = signalConsts.nameOffsetY;
|
||||
const fleetModePath: number[] = [];
|
||||
signalConsts.fleetModePath.forEach((item: number, index: number) => {
|
||||
if (!(index % 2)) {
|
||||
fleetModePath.push(
|
||||
item + signalConsts.levelLampPostLength + signalConsts.lampRadius * 2
|
||||
);
|
||||
} else {
|
||||
fleetModePath.push(item);
|
||||
}
|
||||
});
|
||||
this.fleetModePath = fleetModePath;
|
||||
}
|
||||
new(): Signal {
|
||||
return new Signal();
|
||||
}
|
||||
}
|
167
src/graphics/signal/SignalDrawAssistant.ts
Normal file
167
src/graphics/signal/SignalDrawAssistant.ts
Normal file
@ -0,0 +1,167 @@
|
||||
import { FederatedPointerEvent, Point, Graphics, Color } from 'pixi.js';
|
||||
import {
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
JlDrawApp,
|
||||
JlGraphic,
|
||||
VectorText,
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
import { ISignalData, Signal, SignalTemplate } from './Signal';
|
||||
|
||||
export interface ISignalDrawOptions {
|
||||
newData: () => ISignalData;
|
||||
}
|
||||
|
||||
export class SignalDraw extends GraphicDrawAssistant<
|
||||
SignalTemplate,
|
||||
ISignalData
|
||||
> {
|
||||
point: Point = new Point(0, 0);
|
||||
codeGraph: VectorText = new VectorText('');
|
||||
lampPost: Graphics = new Graphics();
|
||||
circularLamp: Graphics = new Graphics();
|
||||
humanControl: Graphics = new Graphics();
|
||||
fleetMode: Graphics = new Graphics();
|
||||
logicMode: Graphics = new Graphics();
|
||||
|
||||
constructor(app: JlDrawApp, createData: () => ISignalData) {
|
||||
super(
|
||||
app,
|
||||
new SignalTemplate(),
|
||||
createData,
|
||||
'svguse:../drawIcon.svg#icon-signal',
|
||||
'信号机Signal'
|
||||
);
|
||||
this.container.addChild(this.codeGraph);
|
||||
this.container.addChild(this.lampPost);
|
||||
this.container.addChild(this.circularLamp);
|
||||
this.container.addChild(this.humanControl);
|
||||
this.container.addChild(this.fleetMode);
|
||||
this.container.addChild(this.logicMode);
|
||||
signalInteraction.init(app);
|
||||
}
|
||||
|
||||
bind(): void {
|
||||
super.bind();
|
||||
}
|
||||
unbind(): void {
|
||||
super.unbind();
|
||||
}
|
||||
|
||||
clearCache(): void {
|
||||
//this.codeGraph.clear();
|
||||
}
|
||||
onRightClick(): void {
|
||||
this.createAndStore(true);
|
||||
}
|
||||
onLeftDown(e: FederatedPointerEvent): void {
|
||||
const { x, y } = this.toCanvasCoordinates(e.global);
|
||||
const p = new Point(x, y);
|
||||
this.point = p;
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
redraw(p: Point): void {
|
||||
const codeGraph = this.codeGraph;
|
||||
const template = this.graphicTemplate;
|
||||
this.point.set(p.x, p.y);
|
||||
this.lampPost.lineStyle(
|
||||
template.lineWidth,
|
||||
new Color(template.lampPostColor)
|
||||
);
|
||||
this.lampPost.moveTo(0, -template.verticalLampPostLength / 2);
|
||||
this.lampPost.lineTo(0, template.verticalLampPostLength / 2);
|
||||
|
||||
this.lampPost.moveTo(0, 0);
|
||||
this.lampPost.lineTo(template.levelLampPostLength, 0);
|
||||
|
||||
this.lampPost.position.set(p.x, p.y);
|
||||
this.circularLamp.beginFill(template.lampColor, 1);
|
||||
this.circularLamp.drawCircle(
|
||||
template.levelLampPostLength + template.lampRadius,
|
||||
0,
|
||||
template.lampRadius
|
||||
);
|
||||
this.circularLamp.endFill();
|
||||
this.circularLamp.position.set(p.x, p.y);
|
||||
this.humanControl.beginFill(template.humanControlColor, 1);
|
||||
this.humanControl.drawPolygon(template.humanControlPath);
|
||||
this.humanControl.endFill();
|
||||
this.humanControl.position.set(p.x, p.y);
|
||||
this.fleetMode.beginFill(template.fleetModeColor, 1);
|
||||
this.fleetMode.drawPolygon(template.fleetModePath);
|
||||
this.fleetMode.endFill();
|
||||
this.fleetMode.position.set(p.x, p.y);
|
||||
this.logicMode.lineStyle(
|
||||
template.logicModeLineWidth,
|
||||
new Color(template.logicModeColor)
|
||||
);
|
||||
this.logicMode.moveTo(
|
||||
template.levelLampPostLength +
|
||||
template.lampRadius -
|
||||
template.logicModeDistance,
|
||||
template.logicModeDistance
|
||||
);
|
||||
this.logicMode.lineTo(
|
||||
template.levelLampPostLength +
|
||||
template.lampRadius +
|
||||
template.logicModeDistance,
|
||||
-template.logicModeDistance
|
||||
);
|
||||
this.logicMode.moveTo(
|
||||
template.levelLampPostLength +
|
||||
template.lampRadius -
|
||||
template.logicModeDistance,
|
||||
-template.logicModeDistance
|
||||
);
|
||||
this.logicMode.lineTo(
|
||||
template.levelLampPostLength +
|
||||
template.lampRadius +
|
||||
template.logicModeDistance,
|
||||
template.logicModeDistance
|
||||
);
|
||||
this.logicMode.position.set(p.x, p.y);
|
||||
codeGraph.text = '信号机Signal';
|
||||
|
||||
codeGraph.style.fill = template.codeColor;
|
||||
codeGraph.setVectorFontSize(template.codeFontSize);
|
||||
codeGraph.anchor.set(0.5);
|
||||
codeGraph.style.fill = template.codeColor;
|
||||
codeGraph.position.set(p.x, p.y + template.nameOffsetY);
|
||||
}
|
||||
prepareData(data: ISignalData): boolean {
|
||||
const template = this.graphicTemplate;
|
||||
data.point = this.point;
|
||||
data.codeColor = template.codeColor;
|
||||
data.codeFontSize = template.codeFontSize;
|
||||
data.direction = template.direction;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class signalInteraction extends GraphicInteractionPlugin<Signal> {
|
||||
static Name = 'signal_transform';
|
||||
constructor(app: JlDrawApp) {
|
||||
super(signalInteraction.Name, app);
|
||||
}
|
||||
static init(app: JlDrawApp) {
|
||||
return new signalInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Signal[] | undefined {
|
||||
return grahpics
|
||||
.filter((g) => g.type === Signal.Type)
|
||||
.map((g) => g as Signal);
|
||||
}
|
||||
bind(g: Signal): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.scalable = true;
|
||||
g.rotatable = true;
|
||||
}
|
||||
unbind(g: Signal): void {
|
||||
g.eventMode = 'none';
|
||||
g.scalable = false;
|
||||
g.rotatable = false;
|
||||
}
|
||||
}
|
@ -21,7 +21,13 @@ export class StationDraw extends GraphicDrawAssistant<
|
||||
codeGraph: VectorText = new VectorText('');
|
||||
|
||||
constructor(app: JlDrawApp, createData: () => IStationData) {
|
||||
super(app, new StationTemplate(), createData, Station.Type, '车站Station');
|
||||
super(
|
||||
app,
|
||||
new StationTemplate(),
|
||||
createData,
|
||||
'svguse:../drawIcon.svg#icon-station',
|
||||
'车站Station'
|
||||
);
|
||||
this.container.addChild(this.codeGraph);
|
||||
stationInteraction.init(app);
|
||||
}
|
||||
@ -36,9 +42,6 @@ export class StationDraw extends GraphicDrawAssistant<
|
||||
clearCache(): void {
|
||||
//this.codeGraph.clear();
|
||||
}
|
||||
onRightClick(): void {
|
||||
this.createAndStore(true);
|
||||
}
|
||||
onLeftDown(e: FederatedPointerEvent): void {
|
||||
const { x, y } = this.toCanvasCoordinates(e.global);
|
||||
const p = new Point(x, y);
|
||||
|
@ -20,7 +20,13 @@ export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
|
||||
codeRact: Graphics = new Graphics();
|
||||
|
||||
constructor(app: JlDrawApp, createData: () => ITrainData) {
|
||||
super(app, new TrainTemplate(), createData, Train.Type, '列车Train');
|
||||
super(
|
||||
app,
|
||||
new TrainTemplate(),
|
||||
createData,
|
||||
'directions_bus_filled',
|
||||
'列车Train'
|
||||
);
|
||||
this.container.addChild(this.arrowLeft);
|
||||
this.container.addChild(this.pauseLeft);
|
||||
this.container.addChild(this.codeRact);
|
||||
@ -40,9 +46,6 @@ export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
|
||||
this.pauseLeft.clear();
|
||||
this.codeRact.clear();
|
||||
}
|
||||
onRightClick(): void {
|
||||
this.createAndStore(true);
|
||||
}
|
||||
onLeftDown(e: FederatedPointerEvent): void {
|
||||
const { x, y } = this.toCanvasCoordinates(e.global);
|
||||
const p = new Point(x, y);
|
||||
|
@ -894,7 +894,8 @@ export class GraphicApp extends EventEmitter<GraphicAppEvents> {
|
||||
}
|
||||
}
|
||||
this.interactionPluginMap.forEach((plugin) => {
|
||||
plugin.pause();
|
||||
// plugin.pause();
|
||||
this.doPauseInteractionPlugin(plugin);
|
||||
});
|
||||
this.canvas.destroy(true);
|
||||
this.viewport.destroy();
|
||||
|
@ -2,15 +2,41 @@
|
||||
<q-layout view="hHh LpR fFf">
|
||||
<q-header reveal class="bg-primary text-white">
|
||||
<q-toolbar>
|
||||
<q-btn dense flat round icon="menu" @click="toggleLeftDrawer" />
|
||||
|
||||
<q-toolbar-title>
|
||||
<q-avatar>
|
||||
<img src="https://cdn.quasar.dev/logo-v2/svg/logo-mono-white.svg" />
|
||||
</q-avatar>
|
||||
Title
|
||||
<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>
|
||||
<q-item-section>另存为</q-item-section>
|
||||
</q-item> -->
|
||||
<q-item clickable v-close-popup>
|
||||
<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 color="info" label="返回" @click="backConfirm" />
|
||||
<q-btn dense flat round icon="menu" @click="toggleRightDrawer" />
|
||||
</q-toolbar>
|
||||
<q-resize-observer @resize="onHeaderResize" />
|
||||
@ -108,21 +134,19 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import DrawProperties from 'src/components/draw-app/DrawProperties.vue';
|
||||
import { getDrawApp, loadDrawDatas } from 'src/drawApp';
|
||||
import { getDrawApp, loadDrawDatas, saveDrawDatas } from 'src/drawApp';
|
||||
import { JlDrawApp } from 'src/jl-graphic';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
console.log(useRoute().fullPath);
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
|
||||
const leftDrawerOpen = ref(false);
|
||||
const rightDrawerOpen = ref(false);
|
||||
function toggleLeftDrawer() {
|
||||
leftDrawerOpen.value = !leftDrawerOpen.value;
|
||||
onResize();
|
||||
}
|
||||
function toggleRightDrawer() {
|
||||
rightDrawerOpen.value = !rightDrawerOpen.value;
|
||||
onResize();
|
||||
@ -130,14 +154,54 @@ function toggleRightDrawer() {
|
||||
|
||||
const link = ref('outbox');
|
||||
|
||||
//工具栏所用
|
||||
const selectUtil = ref();
|
||||
const utilsOption: ControlItem[] = reactive([]);
|
||||
const drawSelect = (item: string) => {
|
||||
getDrawApp()?.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) {
|
||||
drawStore.setDraftId(+route.params.id as number);
|
||||
const drawApp = drawStore.initDrawApp(dom);
|
||||
loadDrawDatas(drawApp);
|
||||
onResize();
|
||||
} else {
|
||||
drawStore.setDraftId(null);
|
||||
}
|
||||
const drawAssistants = (getDrawApp()?._options as { drawAssistants: [] })
|
||||
.drawAssistants;
|
||||
drawAssistants.forEach(
|
||||
(da: { name: string; icon: string; description: string }) => {
|
||||
utilsOption.push(
|
||||
new ControlItem(
|
||||
da.name,
|
||||
da.icon,
|
||||
da.description ? da.description : da.name
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const canvasWidth = ref(0);
|
||||
@ -177,6 +241,14 @@ function onResize() {
|
||||
drawApp.onDomResize(canvasWidth.value, canvasHeight.value);
|
||||
}
|
||||
}
|
||||
function saveAllDrawDatas() {
|
||||
const drawApp = getDrawApp();
|
||||
saveDrawDatas(drawApp as JlDrawApp);
|
||||
}
|
||||
|
||||
function backConfirm() {
|
||||
router.go(-1);
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
drawStore.destroy();
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<q-layout view="hHh Lpr lFf">
|
||||
<q-header elevated>
|
||||
<q-resize-observer @resize="onHeaderResize" />
|
||||
<q-toolbar>
|
||||
<q-btn
|
||||
flat
|
||||
@ -33,13 +34,16 @@
|
||||
</q-drawer>
|
||||
|
||||
<q-page-container>
|
||||
<router-view />
|
||||
<q-resize-observer @resize="onResize" />
|
||||
<q-scroll-area :style="{ height: scrollHeight + 'px' }">
|
||||
<router-view :sizeHeight="scrollHeight" />
|
||||
</q-scroll-area>
|
||||
</q-page-container>
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { ref, reactive } from 'vue';
|
||||
import SysMenu from 'src/components/SysMenu.vue';
|
||||
|
||||
const leftDrawerOpen = ref(false);
|
||||
@ -47,4 +51,13 @@ const leftDrawerOpen = ref(false);
|
||||
function toggleLeftDrawer() {
|
||||
leftDrawerOpen.value = !leftDrawerOpen.value;
|
||||
}
|
||||
const scrollHeight = ref(100);
|
||||
function onResize() {
|
||||
scrollHeight.value = window.innerHeight - headerSize.height;
|
||||
}
|
||||
const headerSize = reactive({} as { width: number; height: number });
|
||||
function onHeaderResize(size: { width: number; height: number }) {
|
||||
headerSize.width = size.width;
|
||||
headerSize.height = size.height;
|
||||
}
|
||||
</script>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<q-table
|
||||
ref="tableRef"
|
||||
title="草稿图"
|
||||
:style="{ height: tableHeight + 'px' }"
|
||||
:rows="rows"
|
||||
:columns="columnDefs"
|
||||
row-key="id"
|
||||
@ -103,7 +104,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { useQuasar, type QTableColumn } from 'quasar';
|
||||
import {
|
||||
pageQuery,
|
||||
@ -114,6 +115,17 @@ import {
|
||||
|
||||
const $q = useQuasar();
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
sizeHeight: number;
|
||||
}>(),
|
||||
{ sizeHeight: 500 }
|
||||
);
|
||||
|
||||
const tableHeight = computed(() => {
|
||||
return props.sizeHeight - 32;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
tableRef.value.requestServerInteraction();
|
||||
});
|
||||
|
@ -15,10 +15,11 @@ export namespace graphicData {
|
||||
stations?: Station[];
|
||||
Rects?: Rect[];
|
||||
train?: Train[];
|
||||
signals?: Signal[];
|
||||
turnouts?: Turnout[];
|
||||
}) {
|
||||
super();
|
||||
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5, 6, 7, 8], this.#one_of_decls);
|
||||
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5, 6, 7, 8, 9], this.#one_of_decls);
|
||||
if (!Array.isArray(data) && typeof data == "object") {
|
||||
if ("canvas" in data && data.canvas != undefined) {
|
||||
this.canvas = data.canvas;
|
||||
@ -41,6 +42,9 @@ export namespace graphicData {
|
||||
if ("train" in data && data.train != undefined) {
|
||||
this.train = data.train;
|
||||
}
|
||||
if ("signals" in data && data.signals != undefined) {
|
||||
this.signals = data.signals;
|
||||
}
|
||||
if ("turnouts" in data && data.turnouts != undefined) {
|
||||
this.turnouts = data.turnouts;
|
||||
}
|
||||
@ -91,11 +95,17 @@ export namespace graphicData {
|
||||
set train(value: Train[]) {
|
||||
pb_1.Message.setRepeatedWrapperField(this, 7, value);
|
||||
}
|
||||
get signals() {
|
||||
return pb_1.Message.getRepeatedWrapperField(this, Signal, 8) as Signal[];
|
||||
}
|
||||
set signals(value: Signal[]) {
|
||||
pb_1.Message.setRepeatedWrapperField(this, 8, value);
|
||||
}
|
||||
get turnouts() {
|
||||
return pb_1.Message.getRepeatedWrapperField(this, Turnout, 8) as Turnout[];
|
||||
return pb_1.Message.getRepeatedWrapperField(this, Turnout, 9) as Turnout[];
|
||||
}
|
||||
set turnouts(value: Turnout[]) {
|
||||
pb_1.Message.setRepeatedWrapperField(this, 8, value);
|
||||
pb_1.Message.setRepeatedWrapperField(this, 9, value);
|
||||
}
|
||||
static fromObject(data: {
|
||||
canvas?: ReturnType<typeof Canvas.prototype.toObject>;
|
||||
@ -105,6 +115,7 @@ export namespace graphicData {
|
||||
stations?: ReturnType<typeof Station.prototype.toObject>[];
|
||||
Rects?: ReturnType<typeof Rect.prototype.toObject>[];
|
||||
train?: ReturnType<typeof Train.prototype.toObject>[];
|
||||
signals?: ReturnType<typeof Signal.prototype.toObject>[];
|
||||
turnouts?: ReturnType<typeof Turnout.prototype.toObject>[];
|
||||
}): RtssGraphicStorage {
|
||||
const message = new RtssGraphicStorage({});
|
||||
@ -129,6 +140,9 @@ export namespace graphicData {
|
||||
if (data.train != null) {
|
||||
message.train = data.train.map(item => Train.fromObject(item));
|
||||
}
|
||||
if (data.signals != null) {
|
||||
message.signals = data.signals.map(item => Signal.fromObject(item));
|
||||
}
|
||||
if (data.turnouts != null) {
|
||||
message.turnouts = data.turnouts.map(item => Turnout.fromObject(item));
|
||||
}
|
||||
@ -143,6 +157,7 @@ export namespace graphicData {
|
||||
stations?: ReturnType<typeof Station.prototype.toObject>[];
|
||||
Rects?: ReturnType<typeof Rect.prototype.toObject>[];
|
||||
train?: ReturnType<typeof Train.prototype.toObject>[];
|
||||
signals?: ReturnType<typeof Signal.prototype.toObject>[];
|
||||
turnouts?: ReturnType<typeof Turnout.prototype.toObject>[];
|
||||
} = {};
|
||||
if (this.canvas != null) {
|
||||
@ -166,6 +181,9 @@ export namespace graphicData {
|
||||
if (this.train != null) {
|
||||
data.train = this.train.map((item: Train) => item.toObject());
|
||||
}
|
||||
if (this.signals != null) {
|
||||
data.signals = this.signals.map((item: Signal) => item.toObject());
|
||||
}
|
||||
if (this.turnouts != null) {
|
||||
data.turnouts = this.turnouts.map((item: Turnout) => item.toObject());
|
||||
}
|
||||
@ -189,8 +207,10 @@ export namespace graphicData {
|
||||
writer.writeRepeatedMessage(6, this.Rects, (item: Rect) => item.serialize(writer));
|
||||
if (this.train.length)
|
||||
writer.writeRepeatedMessage(7, this.train, (item: Train) => item.serialize(writer));
|
||||
if (this.signals.length)
|
||||
writer.writeRepeatedMessage(8, this.signals, (item: Signal) => item.serialize(writer));
|
||||
if (this.turnouts.length)
|
||||
writer.writeRepeatedMessage(8, this.turnouts, (item: Turnout) => item.serialize(writer));
|
||||
writer.writeRepeatedMessage(9, this.turnouts, (item: Turnout) => item.serialize(writer));
|
||||
if (!w)
|
||||
return writer.getResultBuffer();
|
||||
}
|
||||
@ -222,7 +242,10 @@ export namespace graphicData {
|
||||
reader.readMessage(message.train, () => pb_1.Message.addToRepeatedWrapperField(message, 7, Train.deserialize(reader), Train));
|
||||
break;
|
||||
case 8:
|
||||
reader.readMessage(message.turnouts, () => pb_1.Message.addToRepeatedWrapperField(message, 8, Turnout.deserialize(reader), Turnout));
|
||||
reader.readMessage(message.signals, () => pb_1.Message.addToRepeatedWrapperField(message, 8, Signal.deserialize(reader), Signal));
|
||||
break;
|
||||
case 9:
|
||||
reader.readMessage(message.turnouts, () => pb_1.Message.addToRepeatedWrapperField(message, 9, Turnout.deserialize(reader), Turnout));
|
||||
break;
|
||||
default: reader.skipField();
|
||||
}
|
||||
@ -2486,4 +2509,192 @@ export namespace graphicData {
|
||||
return Turnout.deserialize(bytes);
|
||||
}
|
||||
}
|
||||
export class Signal extends pb_1.Message {
|
||||
#one_of_decls: number[][] = [];
|
||||
constructor(data?: any[] | {
|
||||
common?: CommonInfo;
|
||||
code?: string;
|
||||
codeColor?: string;
|
||||
codeFontSize?: number;
|
||||
point?: Point;
|
||||
direction?: string;
|
||||
}) {
|
||||
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 ("codeColor" in data && data.codeColor != undefined) {
|
||||
this.codeColor = data.codeColor;
|
||||
}
|
||||
if ("codeFontSize" in data && data.codeFontSize != undefined) {
|
||||
this.codeFontSize = data.codeFontSize;
|
||||
}
|
||||
if ("point" in data && data.point != undefined) {
|
||||
this.point = data.point;
|
||||
}
|
||||
if ("direction" in data && data.direction != undefined) {
|
||||
this.direction = data.direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
get common() {
|
||||
return pb_1.Message.getWrapperField(this, CommonInfo, 1) as CommonInfo;
|
||||
}
|
||||
set common(value: 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 codeColor() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 3, "") as string;
|
||||
}
|
||||
set codeColor(value: string) {
|
||||
pb_1.Message.setField(this, 3, value);
|
||||
}
|
||||
get codeFontSize() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 4, 0) as number;
|
||||
}
|
||||
set codeFontSize(value: number) {
|
||||
pb_1.Message.setField(this, 4, value);
|
||||
}
|
||||
get point() {
|
||||
return pb_1.Message.getWrapperField(this, Point, 5) as Point;
|
||||
}
|
||||
set point(value: Point) {
|
||||
pb_1.Message.setWrapperField(this, 5, value);
|
||||
}
|
||||
get has_point() {
|
||||
return pb_1.Message.getField(this, 5) != null;
|
||||
}
|
||||
get direction() {
|
||||
return pb_1.Message.getFieldWithDefault(this, 6, "") as string;
|
||||
}
|
||||
set direction(value: string) {
|
||||
pb_1.Message.setField(this, 6, value);
|
||||
}
|
||||
static fromObject(data: {
|
||||
common?: ReturnType<typeof CommonInfo.prototype.toObject>;
|
||||
code?: string;
|
||||
codeColor?: string;
|
||||
codeFontSize?: number;
|
||||
point?: ReturnType<typeof Point.prototype.toObject>;
|
||||
direction?: string;
|
||||
}): Signal {
|
||||
const message = new Signal({});
|
||||
if (data.common != null) {
|
||||
message.common = CommonInfo.fromObject(data.common);
|
||||
}
|
||||
if (data.code != null) {
|
||||
message.code = data.code;
|
||||
}
|
||||
if (data.codeColor != null) {
|
||||
message.codeColor = data.codeColor;
|
||||
}
|
||||
if (data.codeFontSize != null) {
|
||||
message.codeFontSize = data.codeFontSize;
|
||||
}
|
||||
if (data.point != null) {
|
||||
message.point = Point.fromObject(data.point);
|
||||
}
|
||||
if (data.direction != null) {
|
||||
message.direction = data.direction;
|
||||
}
|
||||
return message;
|
||||
}
|
||||
toObject() {
|
||||
const data: {
|
||||
common?: ReturnType<typeof CommonInfo.prototype.toObject>;
|
||||
code?: string;
|
||||
codeColor?: string;
|
||||
codeFontSize?: number;
|
||||
point?: ReturnType<typeof Point.prototype.toObject>;
|
||||
direction?: string;
|
||||
} = {};
|
||||
if (this.common != null) {
|
||||
data.common = this.common.toObject();
|
||||
}
|
||||
if (this.code != null) {
|
||||
data.code = this.code;
|
||||
}
|
||||
if (this.codeColor != null) {
|
||||
data.codeColor = this.codeColor;
|
||||
}
|
||||
if (this.codeFontSize != null) {
|
||||
data.codeFontSize = this.codeFontSize;
|
||||
}
|
||||
if (this.point != null) {
|
||||
data.point = this.point.toObject();
|
||||
}
|
||||
if (this.direction != null) {
|
||||
data.direction = this.direction;
|
||||
}
|
||||
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.codeColor.length)
|
||||
writer.writeString(3, this.codeColor);
|
||||
if (this.codeFontSize != 0)
|
||||
writer.writeInt32(4, this.codeFontSize);
|
||||
if (this.has_point)
|
||||
writer.writeMessage(5, this.point, () => this.point.serialize(writer));
|
||||
if (this.direction.length)
|
||||
writer.writeString(6, this.direction);
|
||||
if (!w)
|
||||
return writer.getResultBuffer();
|
||||
}
|
||||
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): Signal {
|
||||
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new Signal();
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup())
|
||||
break;
|
||||
switch (reader.getFieldNumber()) {
|
||||
case 1:
|
||||
reader.readMessage(message.common, () => message.common = CommonInfo.deserialize(reader));
|
||||
break;
|
||||
case 2:
|
||||
message.code = reader.readString();
|
||||
break;
|
||||
case 3:
|
||||
message.codeColor = reader.readString();
|
||||
break;
|
||||
case 4:
|
||||
message.codeFontSize = reader.readInt32();
|
||||
break;
|
||||
case 5:
|
||||
reader.readMessage(message.point, () => message.point = Point.deserialize(reader));
|
||||
break;
|
||||
case 6:
|
||||
message.direction = reader.readString();
|
||||
break;
|
||||
default: reader.skipField();
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
serializeBinary(): Uint8Array {
|
||||
return this.serialize();
|
||||
}
|
||||
static deserializeBinary(bytes: Uint8Array): Signal {
|
||||
return Signal.deserialize(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ export const useDrawStore = defineStore('draw', {
|
||||
state: () => ({
|
||||
drawAssistant: null as DrawAssistant | null,
|
||||
selectedGraphics: null as JlGraphic[] | null,
|
||||
draftId: null as number | null,
|
||||
}),
|
||||
getters: {
|
||||
drawMode: (state) => state.drawAssistant != null,
|
||||
@ -74,5 +75,8 @@ export const useDrawStore = defineStore('draw', {
|
||||
this.selectedGraphics = null;
|
||||
destroyDrawApp();
|
||||
},
|
||||
setDraftId(id: number | null) {
|
||||
this.draftId = id;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user