绘制代码备用

This commit is contained in:
joylink_zhaoerwei 2024-09-19 18:04:58 +08:00
parent 0709b1392d
commit 3387d4536e
16 changed files with 735 additions and 396 deletions

View File

@ -15,7 +15,8 @@ export interface DraftItem {
id: number; id: number;
name: string; name: string;
dataType: DraftDataType; dataType: DraftDataType;
data: []; options: { style: IscsStyle };
data: string;
userId: number; userId: number;
isShared: boolean; isShared: boolean;
createdAt: string; createdAt: string;
@ -42,12 +43,12 @@ export async function draftPageQuery(
userDraftIscsDataPaging(paging: $paging, query: $query) { userDraftIscsDataPaging(paging: $paging, query: $query) {
total total
data { data {
id name dataType createdAt updatedAt isShared id name dataType createdAt updatedAt isShared options {style}
} }
} }
} }
`; `;
const response = await api.post(``, { const response = await api.post('', {
query, query,
variables: params, variables: params,
}); });
@ -78,7 +79,7 @@ export function createDraft(params: CreateDraftIscsDto) {
} }
} }
`; `;
return api.post(``, { return api.post('', {
query: mutation, query: mutation,
variables: params, variables: params,
}); });
@ -97,7 +98,7 @@ export function deleteDraft(id: number) {
const variables = { const variables = {
id, id,
}; };
return api.post(``, { return api.post('', {
query: mutation, query: mutation,
variables, variables,
}); });
@ -109,8 +110,21 @@ export function deleteDraft(id: number) {
* @returns * @returns
*/ */
export async function getDraft(id: number): Promise<DraftItem> { export async function getDraft(id: number): Promise<DraftItem> {
const response = await api.get(`${DraftUriBase}/${id}`); const query = `
return response.data; query draftData($id: Int) {
draftData(id: $id){
data
}
}
`;
const variables = {
id,
};
const response = await api.post('', {
query,
variables,
});
return response.data.data.draftData;
} }
/** /**
@ -118,13 +132,23 @@ export async function getDraft(id: number): Promise<DraftItem> {
* @param data * @param data
* @returns * @returns
*/ */
export function saveDraft( export function saveDraft(data: { id: number; data: string }) {
id: number, const mutation = `
data: { mutation updateDraftDataData($id: Int,$data: String) {
proto: string; updateDraftDataData(id: $id,data: $data){
id
} }
) { }
return api.put(`${DraftUriBase}/${id}`, data); `;
const variables = {
id: 1,
data: data.data,
};
console.log(data);
return api.post('', {
query: mutation,
variables: variables,
});
} }
/** /**

View File

@ -0,0 +1,202 @@
<template>
<q-dialog
ref="dialogRef"
@hide="onHide"
v-bind="$attrs"
@show="emit('show')"
transitionShow="jump-up"
transitionHide="jump-down"
class="column"
>
<q-card
:style="{
transform: `translate3d(${offset.x}px, ${offset.y}px, 1px)`,
background: `${props.bgColor}`,
border: `${props.bgBorder}`,
}"
style="max-width: 2000px"
>
<!-- <q-scroll-area
v-if="props.height"
id="draggable-dialog-scroll"
:style="`width: ${props.width}px;height: ${props.height}px`"
style="max-height: 90vh"
> -->
<div style="position: sticky; top: 0px; z-index: 9">
<q-bar
ref="headerRef"
class="non-selectable q-gutter-l"
style="
cursor: move;
border-top-right-radius: 0;
border-top-left-radius: 0;
"
:style="`height: ${props.titleHeight}px;background: ${props.titleColor}`"
>
<div
:style="`height: 100%; line-height: ${props.titleHeight}px; color:${props.fontColor};font-size: ${props.fontSize}px;`"
>
{{ props.title }}
</div>
<q-space />
<div style="margin-right: 10px">
<slot name="titleButton"></slot>
</div>
<q-btn
dense
flat
icon="sym_o_close"
v-close-popup
v-if="!canNotClose"
></q-btn>
</q-bar>
</div>
<q-scroll-area
v-if="props.height"
id="draggable-dialog-scroll"
:style="`width: ${dialogWidth}px;height: ${dialogHeight}px`"
style="max-height: calc(90vh - 100px)"
>
<slot></slot>
</q-scroll-area>
<slot name="footer"></slot>
<div
:style="`width: ${dialogWidth}px`"
style="position: sticky; bottom: 0px"
>
<slot name="sticky-footer"></slot>
</div>
<resizable-div-width
v-if="resizableWidth"
:height="dialogHeight - 10"
@drapWidth="drapWidth"
@drapMouseUp="drapMouseUp"
/>
<resizable-div-height
v-if="resizableHeight"
:width="dialogWidth - 10"
@drapHeight="drapHeight"
@drapMouseUp="drapMouseUp"
/>
</q-card>
</q-dialog>
</template>
<script setup lang="ts">
import { QBar, useDialogPluginComponent } from 'quasar';
import { ref, onMounted, onUnmounted, reactive } from 'vue';
import ResizableDivWidth from './ResizableDivWidth.vue';
import ResizableDivHeight from './ResizableDivHeight.vue';
const emit = defineEmits({
...useDialogPluginComponent.emitsObject,
show: () => true,
});
const props = withDefaults(
defineProps<{
title?: string;
titleHeight?: number;
titleColor?: string;
fontColor?: string;
fontSize?: number;
width?: number;
height?: number;
bgColor?: string;
bgBorder?: string;
resizableWidth?: boolean;
resizableHeight?: boolean;
canNotClose?: boolean;
}>(),
{
width: 500,
height: 800,
titleColor: 'rgb(25,118,210)',
titleHeight: 36,
fontSize: 20,
fontColor: 'white',
resizableWidth: false,
resizableHeight: false,
canNotClose: false,
}
);
const { dialogRef, onDialogHide /* , onDialogCancel, onDialogOK */ } =
useDialogPluginComponent();
const headerRef = ref<InstanceType<typeof QBar> | null>(null);
const offset = reactive({
x: 0,
y: 0,
});
const start = { x: 0, y: 0 };
const startOffset = { x: 0, y: 0 };
onMounted(() => {
dialogWidth.value = props.width;
lastDialogWidth = props.width;
dialogHeight.value = props.height;
lastDialogHeight = props.height;
window.addEventListener('mousedown', onMouseDown);
});
onUnmounted(() => {
window.removeEventListener('mousedown', onMouseDown);
});
function onMove(e: MouseEvent) {
let y = e.clientY > startOffset.y ? e.clientY : startOffset.y;
if (y > window.innerHeight - props.titleHeight + startOffset.y) {
y = window.innerHeight - props.titleHeight + startOffset.y;
}
[offset.x, offset.y] = [e.clientX - start.x, y - start.y];
}
function onMouseUp() {
window.removeEventListener('mousemove', onMove);
window.removeEventListener('mouseup', onMouseUp);
startOffset.x = 0;
startOffset.y = 0;
}
function onMouseDown(e: MouseEvent) {
if (!e.target || !headerRef.value?.$el.contains(e.target)) return;
startOffset.x = e.offsetX;
startOffset.y = e.offsetY;
start.x = e.clientX - offset.x;
start.y = e.clientY - offset.y;
window.addEventListener('mousemove', onMove);
window.addEventListener('mouseup', onMouseUp);
}
function onHide() {
emit('hide');
onDialogHide();
}
let lastDialogWidth = 0;
const dialogWidth = ref(0);
function drapWidth(width: number) {
if (
(dialogWidth.value > 300 && width > 0) ||
(dialogWidth.value < 1800 && width < 0)
) {
dialogWidth.value = lastDialogWidth - width * 2 + 15;
}
}
let lastDialogHeight = 0;
const dialogHeight = ref(0);
function drapHeight(height: number) {
if (
(dialogHeight.value > 150 && height > 0) ||
(dialogHeight.value < 750 && height < 0)
) {
dialogHeight.value = lastDialogHeight - height * 2 + 15;
}
}
function drapMouseUp() {
lastDialogWidth = dialogWidth.value;
lastDialogHeight = dialogHeight.value;
}
</script>

View File

@ -0,0 +1,61 @@
<template>
<div
ref="drapBox"
class="drapWidth"
:style="{
width: props.width + 'px',
height: props.height + 'px',
}"
@mousedown.stop="onMouseDown"
/>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
const props = withDefaults(
defineProps<{
width?: number;
height?: number;
}>(),
{
width: 300,
height: 15,
}
);
const drapBox = ref();
onMounted(() => {
drapBox.value.onmousedown = () => {
return false;
};
});
const emit = defineEmits(['drapHeight', 'drapMouseUp']);
function onMouseDown(e: MouseEvent) {
drapBox.value.onmousedown = () => {
return false;
};
if (!e.target) return;
const disY = e.clientY - drapBox.value.offsetTop;
document.onmousemove = (e) => {
let top = e.clientY - disY;
emit('drapHeight', top);
};
document.onmouseup = () => {
emit('drapMouseUp');
document.onmousemove = null;
document.onmouseup = null;
};
}
</script>
<style scoped>
.drapWidth {
position: absolute;
top: 0;
z-index: 9999;
background: red;
opacity: 0;
cursor: n-resize;
}
</style>

View File

@ -0,0 +1,61 @@
<template>
<div
ref="drapBox"
class="drapWidth"
:style="{
width: props.width + 'px',
height: props.height + 'px',
}"
@mousedown.stop="onMouseDown"
/>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
const props = withDefaults(
defineProps<{
width?: number;
height?: number;
}>(),
{
width: 15,
height: 500,
}
);
const drapBox = ref();
onMounted(() => {
drapBox.value.onmousedown = () => {
return false;
};
});
const emit = defineEmits(['drapWidth', 'drapMouseUp']);
function onMouseDown(e: MouseEvent) {
drapBox.value.onmousedown = () => {
return false;
};
if (!e.target) return;
const disX = e.clientX - drapBox.value.offsetLeft;
document.onmousemove = (e) => {
let left = e.clientX - disX;
emit('drapWidth', left);
};
document.onmouseup = () => {
emit('drapMouseUp');
document.onmousemove = null;
document.onmouseup = null;
};
}
</script>
<style scoped>
.drapWidth {
position: absolute;
top: 0;
z-index: 9999;
background: red;
opacity: 0;
cursor: e-resize;
}
</style>

View File

@ -0,0 +1,186 @@
<template>
<q-list bordered separator class="rounded-borders">
<q-expansion-item
bordered
expand-separator
v-for="(configItem, index) in selectConfig"
:key="configItem"
v-model="configItem.expanded"
:label="configItem.code"
@click="toggleItem(index)"
>
<q-card>
<q-item no-wrap class="q-gutter-y-sm column">
<q-input
v-if="props.ableAdd"
outlined
v-model="configItem.code"
label="配置项类型"
lazy-rules
/>
<div class="q-gutter-sm row">
<q-chip
v-for="(item, selectIndex) in configItem.refDevicesCode"
:key="item"
square
color="primary"
text-color="white"
removable
@remove="removeSelect(selectIndex)"
clickable
@click="clickSelectCenter(selectIndex)"
>
{{ item }}
</q-chip>
</div>
<div>
<q-btn
v-show="configItem.refDevicesCode.length > 0"
style="width: 100px"
label="清空选择"
color="red"
class="q-mr-md"
@click="clearAllSelect(index)"
/>
<q-btn
v-if="props.ableAdd"
label="删除配置项"
color="secondary"
@click="deleteSelectConfig(index)"
/>
</div>
</q-item>
</q-card>
</q-expansion-item>
</q-list>
<q-btn
v-if="props.ableAdd"
class="q-mt-md"
label="增加配置项"
color="secondary"
@click="addSelectConfig"
/>
</template>
<script setup lang="ts">
import { inject, ref, watch } from 'vue';
import { IDrawApp, JlGraphic } from 'jl-graphic';
const props = withDefaults(
defineProps<{
drawStore: {
selectedGraphics: JlGraphic[];
getDrawApp(): IDrawApp;
};
ableAdd?: boolean;
}>(),
{ ableAdd: false }
);
const selectConfig = ref<
{
code: string;
refDevices: number[];
refDevicesCode: string[];
expanded: boolean;
}[]
>([
{
code: '配置项模版',
refDevices: [],
refDevicesCode: [],
expanded: false,
},
]);
let selectGraphic: JlGraphic[] = [];
defineExpose({
selectConfig,
selectGraphic,
});
interface GraphicData {
datas: { code: string };
}
const filterSelect = inject('filter') as (g: JlGraphic) => boolean;
watch(
() => props.drawStore.selectedGraphics,
(val) => {
if (val && val.length > 0 && clickIndex !== null) {
const selectFilter = props.drawStore.selectedGraphics?.filter(
filterSelect
) as JlGraphic[];
selectGraphic.push(...selectFilter);
selectGraphic = Array.from(new Set(selectGraphic));
props.drawStore.getDrawApp().updateSelected(...selectGraphic);
selectConfig.value[clickIndex].refDevicesCode = selectGraphic.map((g) =>
(g as JlGraphic & GraphicData).datas.code == ''
? g.id + ''
: (g as JlGraphic & GraphicData).datas.code
);
selectConfig.value[clickIndex].refDevices = selectGraphic.map(
(g) => g.id
) as number[];
}
}
);
let clickIndex: null | number = null;
function toggleItem(index: number) {
const drawApp = props.drawStore.getDrawApp();
selectGraphic = [];
drawApp.updateSelected();
if (selectConfig.value[index].expanded == true) {
clickIndex = index;
const select: JlGraphic[] = [];
selectConfig.value[index].refDevices.forEach((id: number) => {
const g = drawApp.queryStore.queryById(id);
select.push(g);
});
drawApp.updateSelected(...select);
} else {
clickIndex = null;
}
}
function removeSelect(removeIndex: number) {
const clickTarget = selectConfig.value[clickIndex as number];
selectGraphic.splice(removeIndex, 1);
clickTarget.refDevicesCode.splice(removeIndex, 1);
clickTarget.refDevices.splice(removeIndex, 1);
props.drawStore.getDrawApp().updateSelected(...selectGraphic);
}
function clickSelectCenter(index: number) {
const drawApp = props.drawStore.getDrawApp();
const clickTarget = selectConfig.value[clickIndex as number];
const clickGraphic = drawApp.queryStore.queryById(
clickTarget.refDevices[index]
);
drawApp.makeGraphicCenterShow(clickGraphic);
}
function clearAllSelect(index: number) {
selectConfig.value[index].refDevices = [];
selectConfig.value[index].refDevicesCode = [];
selectGraphic = [];
props.drawStore.getDrawApp().updateSelected();
}
function addSelectConfig() {
selectConfig.value.push({
code: '配置项模版',
refDevices: [],
refDevicesCode: [],
expanded: false,
});
}
function deleteSelectConfig(index: number) {
selectConfig.value.splice(index, 1);
selectGraphic = [];
props.drawStore.getDrawApp().updateSelected();
}
</script>

View File

@ -34,9 +34,9 @@
/> />
</q-card-section> </q-card-section>
</template> </template>
<template v-else-if="drawStore.selectedGraphics.length > 1"> <!-- <template v-else-if="drawStore.selectedGraphics.length > 1">
<multiple-select-property></multiple-select-property> <multiple-select-property></multiple-select-property>
</template> </template> -->
</q-card> </q-card>
</div> </div>
</template> </template>

View File

@ -24,8 +24,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { useFormData } from 'src/components/DrawAppFormUtils'; import { useFormData } from 'src/components/DrawAppFormUtils';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { CCTVGraphicData } from 'src/protos/cctv_graphic_data';
import { CCTVButtonData } from 'src/drawApp/graphics/CCTV/CCTVButtonInteraction'; import { CCTVButtonData } from 'src/drawApp/graphics/CCTV/CCTVButtonInteraction';
import { iscsGraphicData } from 'src/protos/iscs_graphic_data';
const { data: cctvButtonModel, onUpdate } = useFormData( const { data: cctvButtonModel, onUpdate } = useFormData(
new CCTVButtonData(), new CCTVButtonData(),
@ -33,8 +33,8 @@ const { data: cctvButtonModel, onUpdate } = useFormData(
); );
const optionsButtonType = [ const optionsButtonType = [
{ label: '方形', value: CCTVGraphicData.CCTVButton.ButtonType.rect }, { label: '方形', value: iscsGraphicData.CCTVButton.ButtonType.rect },
{ label: '监视器', value: CCTVGraphicData.CCTVButton.ButtonType.monitor }, { label: '监视器', value: iscsGraphicData.CCTVButton.ButtonType.monitor },
{ label: '半圆', value: CCTVGraphicData.CCTVButton.ButtonType.semicircle }, { label: '半圆', value: iscsGraphicData.CCTVButton.ButtonType.semicircle },
]; ];
</script> </script>

View File

@ -0,0 +1,76 @@
import { IscsStyle } from 'src/api/DraftApi';
//达实智能(福州一号线)
const DA_SHI_ZHI_NENG = [
{
menuName: '火灾报警',
submenu: [
{ sunMenuName: '站台报警' },
{ sunMenuName: '站厅报警' },
{ sunMenuName: '系统状态' },
],
},
{
menuName: '机电',
submenu: [
{ sunMenuName: '大系统' },
{ sunMenuName: '小系统' },
{ sunMenuName: '水系统' },
{ sunMenuName: '照明' },
{ sunMenuName: '电、扶梯' },
{ sunMenuName: '给排水' },
{ sunMenuName: '模式' },
{ sunMenuName: '隧道通风' },
{ sunMenuName: '时间表' },
{ sunMenuName: '权限交接' },
{ sunMenuName: '传感器' },
{ sunMenuName: '车站网络' },
],
},
{
menuName: '广播',
submenu: [{ sunMenuName: '子目录' }],
},
{
menuName: '乘客信息',
submenu: [{ sunMenuName: '子目录' }],
},
{
menuName: '闭路电视',
submenu: [
{ sunMenuName: '车站控制' },
{ sunMenuName: '车站时序' },
{ sunMenuName: '车站时序编辑' },
{ sunMenuName: '车站设备状态' },
],
},
{
menuName: '屏蔽门',
submenu: [{ sunMenuName: '屏蔽门' }],
},
{
menuName: '售检票',
submenu: [{ sunMenuName: '子目录' }],
},
{
menuName: '门禁',
submenu: [{ sunMenuName: '子目录' }],
},
{
menuName: '防淹门',
submenu: [{ sunMenuName: '子目录' }],
},
{
menuName: '网络状态',
submenu: [{ sunMenuName: '子目录' }],
},
];
export function getIscsStyleConfig(style: IscsStyle) {
switch (style) {
case IscsStyle.DA_SHI_ZHI_NENG:
return DA_SHI_ZHI_NENG;
default:
return DA_SHI_ZHI_NENG;
}
}

View File

@ -20,6 +20,8 @@ import { Rect, RectTemplate } from 'src/graphics/rect/Rect';
import { RectDraw } from 'src/graphics/rect/RectDrawAssistant'; import { RectDraw } from 'src/graphics/rect/RectDrawAssistant';
import { RectData } from './graphics/RectInteraction'; import { RectData } from './graphics/RectInteraction';
import { common } from 'src/protos/common'; import { common } from 'src/protos/common';
import { errorNotify, successNotify } from 'src/utils/CommonNotify';
import { saveDraft } from 'src/api/DraftApi';
const UndoOptions: MenuItemOptions = { const UndoOptions: MenuItemOptions = {
name: '撤销', name: '撤销',
@ -121,7 +123,13 @@ export function saveDrawToServer(base64: string) {
if (!id) { if (!id) {
return; return;
} }
console.log('save' + base64); saveDraft({ id, data: base64 })
.then(() => {
successNotify('保存数据成功!');
})
.catch((err) => {
errorNotify(err.message, err);
});
} }
let UniqueIdPrefix = new iscsGraphicData.UniqueIdOfStationLayout(); let UniqueIdPrefix = new iscsGraphicData.UniqueIdOfStationLayout();

View File

@ -1,26 +1,26 @@
import * as pb_1 from 'google-protobuf'; import * as pb_1 from 'google-protobuf';
import { CCTVGraphicData } from 'src/protos/cctv_graphic_data';
import { GraphicDataBase } from '../GraphicDataBase'; import { GraphicDataBase } from '../GraphicDataBase';
import { import {
CCTVButton, CCTVButton,
ICCTVButtonData, ICCTVButtonData,
} from 'src/graphics/CCTV/cctvButton/CCTVButton'; } from 'src/graphics/CCTV/cctvButton/CCTVButton';
import { iscsGraphicData } from 'src/protos/iscs_graphic_data';
export class CCTVButtonData extends GraphicDataBase implements ICCTVButtonData { export class CCTVButtonData extends GraphicDataBase implements ICCTVButtonData {
constructor(data?: CCTVGraphicData.CCTVButton) { constructor(data?: iscsGraphicData.CCTVButton) {
let cctvButton; let cctvButton;
if (data) { if (data) {
cctvButton = data; cctvButton = data;
} else { } else {
cctvButton = new CCTVGraphicData.CCTVButton({ cctvButton = new iscsGraphicData.CCTVButton({
common: GraphicDataBase.defaultCommonInfo(CCTVButton.Type), common: GraphicDataBase.defaultCommonInfo(CCTVButton.Type),
}); });
} }
super(cctvButton); super(cctvButton);
} }
public get data(): CCTVGraphicData.CCTVButton { public get data(): iscsGraphicData.CCTVButton {
return this.getData<CCTVGraphicData.CCTVButton>(); return this.getData<iscsGraphicData.CCTVButton>();
} }
get code(): string { get code(): string {
@ -29,10 +29,10 @@ export class CCTVButtonData extends GraphicDataBase implements ICCTVButtonData {
set code(v: string) { set code(v: string) {
this.data.code = v; this.data.code = v;
} }
get buttonType(): CCTVGraphicData.CCTVButton.ButtonType { get buttonType(): iscsGraphicData.CCTVButton.ButtonType {
return this.data.buttonType; return this.data.buttonType;
} }
set buttonType(v: CCTVGraphicData.CCTVButton.ButtonType) { set buttonType(v: iscsGraphicData.CCTVButton.ButtonType) {
this.data.buttonType = v; this.data.buttonType = v;
} }
clone(): CCTVButtonData { clone(): CCTVButtonData {

View File

@ -6,10 +6,10 @@ import {
KeyListener, KeyListener,
newDrawApp, newDrawApp,
} from 'jl-graphic'; } from 'jl-graphic';
import { CCTVGraphicData } from 'src/protos/cctv_graphic_data';
import { fromUint8Array } from 'js-base64';
import { import {
initCommonDrawApp, initCommonDrawApp,
loadCommonDrawDatas,
saveCommonDrawDatas, saveCommonDrawDatas,
saveDrawToServer, saveDrawToServer,
} from './commonApp'; } from './commonApp';
@ -17,21 +17,24 @@ import { CCTVButtonData } from './graphics/CCTV/CCTVButtonInteraction';
import { CCTVButtonDraw } from 'src/graphics/CCTV/cctvButton/CCTVButtonDrawAssistant'; import { CCTVButtonDraw } from 'src/graphics/CCTV/cctvButton/CCTVButtonDrawAssistant';
import { CCTVButtonTemplate } from 'src/graphics/CCTV/cctvButton/CCTVButton'; import { CCTVButtonTemplate } from 'src/graphics/CCTV/cctvButton/CCTVButton';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { iscsGraphicData } from 'src/protos/iscs_graphic_data';
import { getDraft } from 'src/api/DraftApi';
import { fromUint8Array, toUint8Array } from 'js-base64';
let drawApp: IDrawApp | null = null; let drawApp: IDrawApp | null = null;
export function getCCTVDrawApp(): IDrawApp | null { export function getIscsDrawApp(): IDrawApp | null {
return drawApp; return drawApp;
} }
export function destroyCCTVDrawApp(): void { export function destroyIscsDrawApp(): void {
if (drawApp) { if (drawApp) {
drawApp.destroy(); drawApp.destroy();
drawApp = null; drawApp = null;
} }
} }
export function initCCTVDrawApp(): IDrawApp { export function initIscsDrawApp(): IDrawApp {
const isSupportDeletion = (g: JlGraphic) => { const isSupportDeletion = (g: JlGraphic) => {
console.log(g); console.log(g);
return true; return true;
@ -63,23 +66,28 @@ export async function loadDrawDatas(): Promise<IGraphicStorage> {
if (!id) { if (!id) {
throw new Error('获取数据异常为获取到草稿地图ID'); throw new Error('获取数据异常为获取到草稿地图ID');
} }
/* const { proto: base64 } = await getDraft(id); const { data: base64 } = await getDraft(id);
if (base64) { if (base64) {
const storage = iscsGraphicData.IscsGraphicStorage.deserialize( const storage = iscsGraphicData.IscsGraphicStorage.deserialize(
toUint8Array(base64) toUint8Array(base64)
); );
const datas = loadCommonDrawDatas(storage);} */ const datas = loadCommonDrawDatas(storage);
storage.cctvButtons.forEach((cctvButton) => {
datas.push(new CCTVButtonData(cctvButton));
});
} else {
return Promise.resolve({ return Promise.resolve({
datas: [], datas: [],
}); });
}
} }
export function saveDrawDatas(app: IDrawApp) { export function saveDrawDatas(app: IDrawApp) {
let storage = new CCTVGraphicData.CCTVGraphicStorage(); let storage = new iscsGraphicData.IscsGraphicStorage();
storage = saveCommonDrawDatas( storage = saveCommonDrawDatas(
app, app,
storage storage
) as CCTVGraphicData.CCTVGraphicStorage; ) as iscsGraphicData.IscsGraphicStorage;
const graphics = app.queryStore.getAllGraphics(); const graphics = app.queryStore.getAllGraphics();
/* graphics.forEach((g) => { /* graphics.forEach((g) => {
if (TrackSection.Type === g.type) { if (TrackSection.Type === g.type) {

View File

@ -1,8 +1,8 @@
import { GraphicData, JlGraphic, JlGraphicTemplate } from 'jl-graphic'; import { GraphicData, JlGraphic, JlGraphicTemplate } from 'jl-graphic';
import CCTV_Button_Assets from './cctv-button-spritesheet.png'; import CCTV_Button_Assets from './cctv-button-spritesheet.png';
import CCTV_Button_JSON from './cctv-button-data.json'; import CCTV_Button_JSON from './cctv-button-data.json';
import { CCTVGraphicData } from 'src/protos/cctv_graphic_data';
import { Assets, Sprite, Spritesheet, Texture } from 'pixi.js'; import { Assets, Sprite, Spritesheet, Texture } from 'pixi.js';
import { iscsGraphicData } from 'src/protos/iscs_graphic_data';
interface CCTVButtonTextures { interface CCTVButtonTextures {
rectPressBtn: Texture; rectPressBtn: Texture;
@ -14,8 +14,8 @@ interface CCTVButtonTextures {
export interface ICCTVButtonData extends GraphicData { export interface ICCTVButtonData extends GraphicData {
get code(): string; get code(): string;
set code(v: string); set code(v: string);
get buttonType(): CCTVGraphicData.CCTVButton.ButtonType; get buttonType(): iscsGraphicData.CCTVButton.ButtonType;
set buttonType(v: CCTVGraphicData.CCTVButton.ButtonType); set buttonType(v: iscsGraphicData.CCTVButton.ButtonType);
} }
export class CCTVButton extends JlGraphic { export class CCTVButton extends JlGraphic {
@ -40,10 +40,10 @@ export class CCTVButton extends JlGraphic {
} }
doRepaint(): void { doRepaint(): void {
if (this.datas.buttonType == CCTVGraphicData.CCTVButton.ButtonType.rect) { if (this.datas.buttonType == iscsGraphicData.CCTVButton.ButtonType.rect) {
this._cctvButton.texture = this.cctvButtonTextures.rectBtn; this._cctvButton.texture = this.cctvButtonTextures.rectBtn;
} else if ( } else if (
this.datas.buttonType == CCTVGraphicData.CCTVButton.ButtonType.monitor this.datas.buttonType == iscsGraphicData.CCTVButton.ButtonType.monitor
) { ) {
this._cctvButton.texture = this.cctvButtonTextures.monitorBtn; this._cctvButton.texture = this.cctvButtonTextures.monitorBtn;
} else { } else {

View File

@ -18,23 +18,23 @@
</q-list> </q-list>
</q-menu> </q-menu>
</q-btn> </q-btn>
<q-btn-toggle <template v-for="item in iscsTypeConfig" :key="item.menuName">
v-model="selectUtil" <q-btn-dropdown color="teal" :label="item.menuName">
color="brown" <q-list>
text-color="white" <q-item
toggle-color="orange" v-for="subItem in item.submenu"
toggle-text-color="black" :key="subItem.submenu"
:options="utilsOption" clickable
@update:model-value="drawSelect" v-close-popup
@click="onTopMenuClick(subItem.sunMenuName)"
> >
<template <q-item-section>
v-for="(ctl, idx) in utilsOption" <q-item-label>{{ subItem.sunMenuName }}</q-item-label>
:key="idx" </q-item-section>
v-slot:[ctl.value] </q-item>
> </q-list>
<q-tooltip>{{ ctl.tip }}</q-tooltip> </q-btn-dropdown>
</template> </template>
</q-btn-toggle>
</q-toolbar-title> </q-toolbar-title>
<q-btn square color="purple" style="margin-right: 10px" icon="search"> <q-btn square color="purple" style="margin-right: 10px" icon="search">
<q-popup-edit <q-popup-edit
@ -100,12 +100,38 @@
</q-card-actions> </q-card-actions>
</q-card> </q-card>
</q-dialog> </q-dialog>
<draggable-dialog
seamless
title="绘制工具"
:width="230"
:height="50"
v-model="showDrawTool"
canNotClose
>
<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>
</draggable-dialog>
<q-resize-observer @resize="onResize" /> <q-resize-observer @resize="onResize" />
</q-layout> </q-layout>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import DrawProperties from 'src/components/draw-app/CCTVDrawProperties.vue'; import DrawProperties from 'src/components/draw-app/IscsDrawProperties.vue';
import { onMounted, reactive, ref, watch } from 'vue'; import { onMounted, reactive, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { successNotify } from 'src/utils/CommonNotify'; import { successNotify } from 'src/utils/CommonNotify';
@ -114,8 +140,10 @@ import { useDrawStore } from 'src/stores/draw-store';
import { CCTVButton } from 'src/graphics/CCTV/cctvButton/CCTVButton'; import { CCTVButton } from 'src/graphics/CCTV/cctvButton/CCTVButton';
import { Arrow } from 'src/graphics/arrow/Arrow'; import { Arrow } from 'src/graphics/arrow/Arrow';
import { TextContent } from 'src/graphics/textContent/TextContent'; import { TextContent } from 'src/graphics/textContent/TextContent';
import { PictureType } from 'src/protos/picture';
import { Rect } from 'src/graphics/rect/Rect'; import { Rect } from 'src/graphics/rect/Rect';
import { getIscsStyleConfig } from 'src/configs/iscsStyleConfig';
import { IscsStyle } from 'src/api/DraftApi';
import DraggableDialog from 'src/components/common/DraggableDialog.vue';
const $q = useQuasar(); const $q = useQuasar();
const route = useRoute(); const route = useRoute();
@ -123,7 +151,7 @@ const router = useRouter();
const searchId = ref(0); const searchId = ref(0);
const drawStore = useDrawStore(); const drawStore = useDrawStore();
const showDrawTool = ref(true);
watch( watch(
() => drawStore.drawMode, () => drawStore.drawMode,
(drawMode) => { (drawMode) => {
@ -188,10 +216,11 @@ const leftMenuConfig = [
{ label: '另存为', click: () => (saveAsDialog.value = true) }, { label: '另存为', click: () => (saveAsDialog.value = true) },
]; ];
let iscsTypeConfig = ref([]);
onMounted(() => { onMounted(() => {
console.log('绘制应用layout mounted'); console.log('绘制应用layout mounted');
const dom = document.getElementById('draw-app-container'); const dom = document.getElementById('draw-app-container');
drawStore.drawPictureType = PictureType.CCTV; iscsTypeConfig.value = getIscsStyleConfig(route.query.iscsStyle as IscsStyle);
if (dom) { if (dom) {
drawStore.setDraftId(+route.params.id as number); drawStore.setDraftId(+route.params.id as number);
const drawApp = drawStore.initDrawApp(); const drawApp = drawStore.initDrawApp();
@ -263,4 +292,9 @@ const saveAsName = ref('');
async function saveAs(name: string) { async function saveAs(name: string) {
successNotify('另存为成功' + name); successNotify('另存为成功' + name);
} }
function onTopMenuClick() {
const drawApp = drawStore.getDrawApp();
drawApp.forceReload();
}
</script> </script>

View File

@ -154,6 +154,7 @@ const tableHeight = computed(() => {
return props.sizeHeight - 32; return props.sizeHeight - 32;
}); });
onMounted(() => { onMounted(() => {
tableRef.value.requestServerInteraction(); tableRef.value.requestServerInteraction();
}); });
@ -314,6 +315,6 @@ async function deleteData(row: DraftItem) {
function goToPath(row: DraftItem) { function goToPath(row: DraftItem) {
let path = `/iscsPainting/${row.id}`; let path = `/iscsPainting/${row.id}`;
router.push({ path: path }); router.push({ path: path, query: { iscsStyle: row.options.style } });
} }
</script> </script>

View File

@ -1,294 +0,0 @@
/**
* Generated by the protoc-gen-ts. DO NOT EDIT!
* compiler version: 5.27.4
* source: cctv_graphic_data.proto
* git: https://github.com/thesayyn/protoc-gen-ts */
import * as dependency_1 from "./iscs_graphic_data";
import * as pb_1 from "google-protobuf";
export namespace CCTVGraphicData {
export class CCTVGraphicStorage extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
canvas?: dependency_1.iscsGraphicData.Canvas;
cctvButtons?: CCTVButton[];
arrows?: dependency_1.iscsGraphicData.Arrow[];
iscsTexts?: dependency_1.iscsGraphicData.IscsText[];
rects?: dependency_1.iscsGraphicData.Rect[];
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("canvas" in data && data.canvas != undefined) {
this.canvas = data.canvas;
}
if ("cctvButtons" in data && data.cctvButtons != undefined) {
this.cctvButtons = data.cctvButtons;
}
if ("arrows" in data && data.arrows != undefined) {
this.arrows = data.arrows;
}
if ("iscsTexts" in data && data.iscsTexts != undefined) {
this.iscsTexts = data.iscsTexts;
}
if ("rects" in data && data.rects != undefined) {
this.rects = data.rects;
}
}
}
get canvas() {
return pb_1.Message.getWrapperField(this, dependency_1.iscsGraphicData.Canvas, 1) as dependency_1.iscsGraphicData.Canvas;
}
set canvas(value: dependency_1.iscsGraphicData.Canvas) {
pb_1.Message.setWrapperField(this, 1, value);
}
get has_canvas() {
return pb_1.Message.getField(this, 1) != null;
}
get cctvButtons() {
return pb_1.Message.getRepeatedWrapperField(this, CCTVButton, 2) as CCTVButton[];
}
set cctvButtons(value: CCTVButton[]) {
pb_1.Message.setRepeatedWrapperField(this, 2, value);
}
get arrows() {
return pb_1.Message.getRepeatedWrapperField(this, dependency_1.iscsGraphicData.Arrow, 3) as dependency_1.iscsGraphicData.Arrow[];
}
set arrows(value: dependency_1.iscsGraphicData.Arrow[]) {
pb_1.Message.setRepeatedWrapperField(this, 3, value);
}
get iscsTexts() {
return pb_1.Message.getRepeatedWrapperField(this, dependency_1.iscsGraphicData.IscsText, 4) as dependency_1.iscsGraphicData.IscsText[];
}
set iscsTexts(value: dependency_1.iscsGraphicData.IscsText[]) {
pb_1.Message.setRepeatedWrapperField(this, 4, value);
}
get rects() {
return pb_1.Message.getRepeatedWrapperField(this, dependency_1.iscsGraphicData.Rect, 5) as dependency_1.iscsGraphicData.Rect[];
}
set rects(value: dependency_1.iscsGraphicData.Rect[]) {
pb_1.Message.setRepeatedWrapperField(this, 5, value);
}
static fromObject(data: {
canvas?: ReturnType<typeof dependency_1.iscsGraphicData.Canvas.prototype.toObject>;
cctvButtons?: ReturnType<typeof CCTVButton.prototype.toObject>[];
arrows?: ReturnType<typeof dependency_1.iscsGraphicData.Arrow.prototype.toObject>[];
iscsTexts?: ReturnType<typeof dependency_1.iscsGraphicData.IscsText.prototype.toObject>[];
rects?: ReturnType<typeof dependency_1.iscsGraphicData.Rect.prototype.toObject>[];
}): CCTVGraphicStorage {
const message = new CCTVGraphicStorage({});
if (data.canvas != null) {
message.canvas = dependency_1.iscsGraphicData.Canvas.fromObject(data.canvas);
}
if (data.cctvButtons != null) {
message.cctvButtons = data.cctvButtons.map(item => CCTVButton.fromObject(item));
}
if (data.arrows != null) {
message.arrows = data.arrows.map(item => dependency_1.iscsGraphicData.Arrow.fromObject(item));
}
if (data.iscsTexts != null) {
message.iscsTexts = data.iscsTexts.map(item => dependency_1.iscsGraphicData.IscsText.fromObject(item));
}
if (data.rects != null) {
message.rects = data.rects.map(item => dependency_1.iscsGraphicData.Rect.fromObject(item));
}
return message;
}
toObject() {
const data: {
canvas?: ReturnType<typeof dependency_1.iscsGraphicData.Canvas.prototype.toObject>;
cctvButtons?: ReturnType<typeof CCTVButton.prototype.toObject>[];
arrows?: ReturnType<typeof dependency_1.iscsGraphicData.Arrow.prototype.toObject>[];
iscsTexts?: ReturnType<typeof dependency_1.iscsGraphicData.IscsText.prototype.toObject>[];
rects?: ReturnType<typeof dependency_1.iscsGraphicData.Rect.prototype.toObject>[];
} = {};
if (this.canvas != null) {
data.canvas = this.canvas.toObject();
}
if (this.cctvButtons != null) {
data.cctvButtons = this.cctvButtons.map((item: CCTVButton) => item.toObject());
}
if (this.arrows != null) {
data.arrows = this.arrows.map((item: dependency_1.iscsGraphicData.Arrow) => item.toObject());
}
if (this.iscsTexts != null) {
data.iscsTexts = this.iscsTexts.map((item: dependency_1.iscsGraphicData.IscsText) => item.toObject());
}
if (this.rects != null) {
data.rects = this.rects.map((item: dependency_1.iscsGraphicData.Rect) => 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.cctvButtons.length)
writer.writeRepeatedMessage(2, this.cctvButtons, (item: CCTVButton) => item.serialize(writer));
if (this.arrows.length)
writer.writeRepeatedMessage(3, this.arrows, (item: dependency_1.iscsGraphicData.Arrow) => item.serialize(writer));
if (this.iscsTexts.length)
writer.writeRepeatedMessage(4, this.iscsTexts, (item: dependency_1.iscsGraphicData.IscsText) => item.serialize(writer));
if (this.rects.length)
writer.writeRepeatedMessage(5, this.rects, (item: dependency_1.iscsGraphicData.Rect) => item.serialize(writer));
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): CCTVGraphicStorage {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new CCTVGraphicStorage();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
reader.readMessage(message.canvas, () => message.canvas = dependency_1.iscsGraphicData.Canvas.deserialize(reader));
break;
case 2:
reader.readMessage(message.cctvButtons, () => pb_1.Message.addToRepeatedWrapperField(message, 2, CCTVButton.deserialize(reader), CCTVButton));
break;
case 3:
reader.readMessage(message.arrows, () => pb_1.Message.addToRepeatedWrapperField(message, 3, dependency_1.iscsGraphicData.Arrow.deserialize(reader), dependency_1.iscsGraphicData.Arrow));
break;
case 4:
reader.readMessage(message.iscsTexts, () => pb_1.Message.addToRepeatedWrapperField(message, 4, dependency_1.iscsGraphicData.IscsText.deserialize(reader), dependency_1.iscsGraphicData.IscsText));
break;
case 5:
reader.readMessage(message.rects, () => pb_1.Message.addToRepeatedWrapperField(message, 5, dependency_1.iscsGraphicData.Rect.deserialize(reader), dependency_1.iscsGraphicData.Rect));
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): CCTVGraphicStorage {
return CCTVGraphicStorage.deserialize(bytes);
}
}
export class CCTVButton extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
common?: dependency_1.iscsGraphicData.CommonInfo;
code?: string;
buttonType?: CCTVButton.ButtonType;
}) {
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 ("buttonType" in data && data.buttonType != undefined) {
this.buttonType = data.buttonType;
}
}
}
get common() {
return pb_1.Message.getWrapperField(this, dependency_1.iscsGraphicData.CommonInfo, 1) as dependency_1.iscsGraphicData.CommonInfo;
}
set common(value: dependency_1.iscsGraphicData.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 buttonType() {
return pb_1.Message.getFieldWithDefault(this, 3, CCTVButton.ButtonType.rect) as CCTVButton.ButtonType;
}
set buttonType(value: CCTVButton.ButtonType) {
pb_1.Message.setField(this, 3, value);
}
static fromObject(data: {
common?: ReturnType<typeof dependency_1.iscsGraphicData.CommonInfo.prototype.toObject>;
code?: string;
buttonType?: CCTVButton.ButtonType;
}): CCTVButton {
const message = new CCTVButton({});
if (data.common != null) {
message.common = dependency_1.iscsGraphicData.CommonInfo.fromObject(data.common);
}
if (data.code != null) {
message.code = data.code;
}
if (data.buttonType != null) {
message.buttonType = data.buttonType;
}
return message;
}
toObject() {
const data: {
common?: ReturnType<typeof dependency_1.iscsGraphicData.CommonInfo.prototype.toObject>;
code?: string;
buttonType?: CCTVButton.ButtonType;
} = {};
if (this.common != null) {
data.common = this.common.toObject();
}
if (this.code != null) {
data.code = this.code;
}
if (this.buttonType != null) {
data.buttonType = this.buttonType;
}
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.buttonType != CCTVButton.ButtonType.rect)
writer.writeEnum(3, this.buttonType);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): CCTVButton {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new CCTVButton();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
reader.readMessage(message.common, () => message.common = dependency_1.iscsGraphicData.CommonInfo.deserialize(reader));
break;
case 2:
message.code = reader.readString();
break;
case 3:
message.buttonType = reader.readEnum();
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): CCTVButton {
return CCTVButton.deserialize(bytes);
}
}
export namespace CCTVButton {
export enum ButtonType {
rect = 0,
monitor = 1,
semicircle = 2
}
}
}

View File

@ -1,14 +1,9 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { import {
initCCTVDrawApp, initIscsDrawApp,
destroyCCTVDrawApp, destroyIscsDrawApp,
getCCTVDrawApp, getIscsDrawApp,
} from 'src/drawApp/cctvApp'; } from 'src/drawApp/iscsApp';
import {
initFASDrawApp,
destroyFASDrawApp,
getFASDrawApp,
} from 'src/drawApp/fasApp';
import { import {
DrawAssistant, DrawAssistant,
GraphicData, GraphicData,
@ -31,16 +26,8 @@ export const useDrawStore = defineStore('draw', {
drawGraphicType: (state) => state.drawAssistant?.type, drawGraphicType: (state) => state.drawAssistant?.type,
drawGraphicName: (state) => state.drawAssistant?.description, drawGraphicName: (state) => state.drawAssistant?.description,
drawGraphicTemplate: (state) => state.drawAssistant?.graphicTemplate, drawGraphicTemplate: (state) => state.drawAssistant?.graphicTemplate,
getApp: (state) => { getApp: () => {
let app = null; const app = getIscsDrawApp();
switch (state.drawPictureType) {
case PictureType.CCTV:
app = getCCTVDrawApp();
break;
case PictureType.FireAlarm:
app = getFASDrawApp();
break;
}
return app; return app;
}, },
selectedGraphicType: (state) => { selectedGraphicType: (state) => {
@ -93,15 +80,7 @@ export const useDrawStore = defineStore('draw', {
app.unbindFormData(form); app.unbindFormData(form);
}, },
initDrawApp() { initDrawApp() {
let app: IDrawApp | null = null; const app = initIscsDrawApp();
switch (this.drawPictureType) {
case PictureType.CCTV:
app = initCCTVDrawApp();
break;
case PictureType.FireAlarm:
app = initFASDrawApp();
break;
}
if (app == null) { if (app == null) {
throw new Error('未初始化app'); throw new Error('未初始化app');
} }
@ -124,14 +103,7 @@ export const useDrawStore = defineStore('draw', {
// console.log('绘制状态清空,绘制应用销毁'); // console.log('绘制状态清空,绘制应用销毁');
this.drawAssistant = null; this.drawAssistant = null;
this.selectedGraphics = null; this.selectedGraphics = null;
switch (this.drawPictureType) { destroyIscsDrawApp();
case PictureType.CCTV:
destroyCCTVDrawApp();
break;
case PictureType.FireAlarm:
destroyFASDrawApp();
break;
}
}, },
setDraftId(id: number | null) { setDraftId(id: number | null) {
this.draftId = id; this.draftId = id;