This commit is contained in:
fan 2023-06-07 14:56:06 +08:00
commit 7c33be246f
14 changed files with 160 additions and 80 deletions

@ -1 +1 @@
Subproject commit 729a3c25b4862396702fdd6199cca158feb90798 Subproject commit fe0ba85437c2601451e3fed4769441907cf8addf

18
public/drawIcon.svg Normal file
View 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

View File

@ -47,6 +47,7 @@ module.exports = configure(function (/* ctx */) {
'roboto-font', // optional, you are not bound to it 'roboto-font', // optional, you are not bound to it
'material-icons', // 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 // 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, // minify: false,
// polyfillModulePreload: true, // polyfillModulePreload: true,
// distDir // distDir
distDir: `dist/${BasePath}`, // distDir: `dist/${BasePath}`,
// extendViteConf (viteConf) {}, // extendViteConf (viteConf) {},
// viteVuePluginOptions: {}, // viteVuePluginOptions: {},

View File

@ -6,9 +6,10 @@ const DraftUriBase = '/api/drafting';
interface Item { interface Item {
id: number; id: number;
name: string; name: string;
proto: Array<string>; proto: string;
createdAt: string; createdAt: string;
updateAt: string; updateAt: string;
creatorId?: number;
} }
export class PagingQueryParams extends PageQueryDto { export class PagingQueryParams extends PageQueryDto {
@ -42,7 +43,7 @@ export function createDraft(draftData: { name: string }) {
* 稿 * 稿
* @param id 稿id * @param id 稿id
*/ */
export function deleteDraft(id: string) { export function deleteDraft(id: number) {
return api.delete(`${DraftUriBase}/${id}`); return api.delete(`${DraftUriBase}/${id}`);
} }
@ -63,6 +64,21 @@ export function publishDraft(data: {
* @param params * @param params
* @returns * @returns
*/ */
export function getDraft(id: string) { export async function getDraft(id: number): Promise<Item> {
return api.get(`${DraftUriBase}/${id}`); 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);
} }

View File

@ -32,6 +32,9 @@ import { StationData } from './graphics/StationInteraction';
import { TrainData } from './graphics/TrainInteraction'; import { TrainData } from './graphics/TrainInteraction';
import { SignalData } from './graphics/SignalInteraction'; import { SignalData } from './graphics/SignalInteraction';
import { graphicData } from 'src/protos/stationLayoutGraphics'; import { graphicData } from 'src/protos/stationLayoutGraphics';
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 { export function fromStoragePoint(p: graphicData.Point): Point {
return new Point(p.x, p.y); return new Point(p.x, p.y);
@ -103,24 +106,12 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
const app = drawApp; const app = drawApp;
app.setOptions({ app.setOptions({
drawAssistants: [ drawAssistants: [
new LinkDraw(app, () => {
return new LinkData();
}),
new RectDraw(app, () => {
return new RectData();
}),
new IscsFanDraw(app, () => {
return new IscsFanData();
}),
new PlatformDraw(app, () => { new PlatformDraw(app, () => {
return new PlatformData(); return new PlatformData();
}), }),
new StationDraw(app, () => { new StationDraw(app, () => {
return new StationData(); return new StationData();
}), }),
new TrainDraw(app, () => {
return new TrainData();
}),
new SignalDraw(app, () => { new SignalDraw(app, () => {
return new SignalData(); return new SignalData();
}), }),
@ -145,30 +136,6 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
DefaultCanvasMenu.open(e.global); DefaultCanvasMenu.open(e.global);
}); });
app.addKeyboardListener(
new KeyListener({
value: 'KeyL',
onPress: () => {
app.interactionPlugin(Link.Type).resume();
},
})
);
app.addKeyboardListener(
new KeyListener({
value: 'KeyR',
onPress: () => {
app.interactionPlugin(Rect.Type).resume();
},
})
);
app.addKeyboardListener(
new KeyListener({
value: 'KeyF',
onPress: () => {
app.interactionPlugin(IscsFan.Type).resume();
},
})
);
app.addKeyboardListener( app.addKeyboardListener(
new KeyListener({ new KeyListener({
value: 'KeyP', value: 'KeyP',
@ -179,20 +146,12 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
); );
app.addKeyboardListener( app.addKeyboardListener(
new KeyListener({ new KeyListener({
value: 'KeyO', value: 'KeyS',
onPress: () => { onPress: () => {
app.interactionPlugin(Station.Type).resume(); app.interactionPlugin(Station.Type).resume();
}, },
}) })
); );
app.addKeyboardListener(
new KeyListener({
value: 'KeyT',
onPress: () => {
app.interactionPlugin(Train.Type).resume();
},
})
);
app.addKeyboardListener( app.addKeyboardListener(
new KeyListener({ new KeyListener({
value: 'KeyH', value: 'KeyH',
@ -201,18 +160,6 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
}, },
}) })
); );
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.addKeyboardListener( app.addKeyboardListener(
new KeyListener({ new KeyListener({
value: 'KeyS', value: 'KeyS',
@ -226,7 +173,7 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
return drawApp; return drawApp;
} }
const StorageKey = 'graphic-storage'; // const StorageKey = 'graphic-storage';
export function saveDrawDatas(app: JlDrawApp) { export function saveDrawDatas(app: JlDrawApp) {
const storage = new graphicData.RtssGraphicStorage(); const storage = new graphicData.RtssGraphicStorage();
const canvasData = app.canvas.saveData(); const canvasData = app.canvas.saveData();
@ -261,13 +208,31 @@ export function saveDrawDatas(app: JlDrawApp) {
}); });
const base64 = fromUint8Array(storage.serialize()); const base64 = fromUint8Array(storage.serialize());
console.log('保存数据', storage); 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); // localStorage.removeItem(StorageKey);
const base64 = localStorage.getItem(StorageKey); // const base64 = localStorage.getItem(StorageKey);
// console.log('加载数据', base64); // console.log('加载数据', base64);
const drawStore = useDrawStore();
const id = drawStore.draftId;
if (!id) {
return;
}
const { proto: base64 } = await getDraft(id);
if (base64) { if (base64) {
const storage = graphicData.RtssGraphicStorage.deserialize( const storage = graphicData.RtssGraphicStorage.deserialize(
toUint8Array(base64) toUint8Array(base64)

View File

@ -15,7 +15,13 @@ export class IscsFanDraw extends GraphicDrawAssistant<
constructor(app: JlDrawApp, createData: () => IIscsFanData) { constructor(app: JlDrawApp, createData: () => IIscsFanData) {
const template = new IscsFanTemplate(); const template = new IscsFanTemplate();
super(app, template, createData, IscsFan.Type, '风机'); super(
app,
template,
createData,
'svguse:../drawIcon.svg#icon-fans',
'风机'
);
IscsFanInteraction.init(app); IscsFanInteraction.init(app);
} }

View File

@ -68,7 +68,7 @@ export class LinkDraw extends GraphicDrawAssistant<LinkTemplate, ILinkData> {
}); });
constructor(app: JlDrawApp, createData: () => 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.container.addChild(this.graphic);
this.graphicTemplate.curve = true; this.graphicTemplate.curve = true;

View File

@ -32,7 +32,7 @@ export class PlatformDraw extends GraphicDrawAssistant<
app, app,
new PlatformTemplate(), new PlatformTemplate(),
createData, createData,
Platform.Type, 'svguse:../drawIcon.svg#icon-platform',
'站台Platform' '站台Platform'
); );
this.container.addChild(this.platformGraphic); this.container.addChild(this.platformGraphic);

View File

@ -44,7 +44,7 @@ export class RectDraw extends GraphicDrawAssistant<RectTemplate, IRectData> {
rectGraphic: Graphics = new Graphics(); rectGraphic: Graphics = new Graphics();
constructor(app: JlDrawApp, createData: () => IRectData) { 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); this.container.addChild(this.rectGraphic);
RectPointsEditPlugin.init(app); RectPointsEditPlugin.init(app);
} }

View File

@ -26,7 +26,13 @@ export class SignalDraw extends GraphicDrawAssistant<
logicMode: Graphics = new Graphics(); logicMode: Graphics = new Graphics();
constructor(app: JlDrawApp, createData: () => ISignalData) { constructor(app: JlDrawApp, createData: () => ISignalData) {
super(app, new SignalTemplate(), createData, Signal.Type, '信号机Signal'); super(
app,
new SignalTemplate(),
createData,
'svguse:../drawIcon.svg#icon-signal',
'信号机Signal'
);
this.container.addChild(this.codeGraph); this.container.addChild(this.codeGraph);
this.container.addChild(this.lampPost); this.container.addChild(this.lampPost);
this.container.addChild(this.circularLamp); this.container.addChild(this.circularLamp);

View File

@ -21,7 +21,13 @@ export class StationDraw extends GraphicDrawAssistant<
codeGraph: VectorText = new VectorText(''); codeGraph: VectorText = new VectorText('');
constructor(app: JlDrawApp, createData: () => IStationData) { 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); this.container.addChild(this.codeGraph);
stationInteraction.init(app); stationInteraction.init(app);
} }

View File

@ -20,7 +20,13 @@ export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
codeRact: Graphics = new Graphics(); codeRact: Graphics = new Graphics();
constructor(app: JlDrawApp, createData: () => ITrainData) { 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.arrowLeft);
this.container.addChild(this.pauseLeft); this.container.addChild(this.pauseLeft);
this.container.addChild(this.codeRact); this.container.addChild(this.codeRact);

View File

@ -5,10 +5,23 @@
<q-btn dense flat round icon="menu" @click="toggleLeftDrawer" /> <q-btn dense flat round icon="menu" @click="toggleLeftDrawer" />
<q-toolbar-title> <q-toolbar-title>
<q-avatar> <q-btn-toggle
<img src="https://cdn.quasar.dev/logo-v2/svg/logo-mono-white.svg" /> v-model="selectUtil"
</q-avatar> color="brown"
Title 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-toolbar-title>
<q-btn dense flat round icon="menu" @click="toggleRightDrawer" /> <q-btn dense flat round icon="menu" @click="toggleRightDrawer" />
@ -110,10 +123,15 @@
import DrawProperties from 'src/components/draw-app/DrawProperties.vue'; import DrawProperties from 'src/components/draw-app/DrawProperties.vue';
import { getDrawApp, loadDrawDatas } from 'src/drawApp'; import { getDrawApp, loadDrawDatas } from 'src/drawApp';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, onUnmounted, ref } from 'vue'; import { onMounted, onUnmounted, reactive, ref } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
console.log(useRoute().fullPath); const route = useRoute();
const selectUtil = ref();
const utilsOption: ControlItem[] = reactive([]);
const drawSelect = (item: string) => {
getDrawApp()?.interactionPlugin(item).resume();
};
const drawStore = useDrawStore(); const drawStore = useDrawStore();
@ -130,14 +148,48 @@ function toggleRightDrawer() {
const link = ref('outbox'); const link = ref('outbox');
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(() => { onMounted(() => {
console.log('绘制应用layout mounted'); console.log('绘制应用layout mounted');
const dom = document.getElementById('draw-app-container'); const dom = document.getElementById('draw-app-container');
if (dom) { if (dom) {
drawStore.setDraftId(+route.params.id as number);
const drawApp = drawStore.initDrawApp(dom); const drawApp = drawStore.initDrawApp(dom);
loadDrawDatas(drawApp); loadDrawDatas(drawApp);
onResize(); 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); const canvasWidth = ref(0);

View File

@ -6,6 +6,7 @@ export const useDrawStore = defineStore('draw', {
state: () => ({ state: () => ({
drawAssistant: null as DrawAssistant | null, drawAssistant: null as DrawAssistant | null,
selectedGraphics: null as JlGraphic[] | null, selectedGraphics: null as JlGraphic[] | null,
draftId: null as number | null,
}), }),
getters: { getters: {
drawMode: (state) => state.drawAssistant != null, drawMode: (state) => state.drawAssistant != null,
@ -74,5 +75,8 @@ export const useDrawStore = defineStore('draw', {
this.selectedGraphics = null; this.selectedGraphics = null;
destroyDrawApp(); destroyDrawApp();
}, },
setDraftId(id: number | null) {
this.draftId = id;
},
}, },
}); });