feat: load standard scene
This commit is contained in:
parent
e3edde1b16
commit
713cf8a022
@ -6,6 +6,7 @@ import type { GroupSceneDetail, SceneDetail, SceneInfo } from './type';
|
||||
const enum API {
|
||||
获取场景 = '/scene/getById',
|
||||
保存场景 = '/scene/saveById',
|
||||
推送场景 = '/scene/pushById',
|
||||
|
||||
获取组场景 = '/scene/getByGroupId',
|
||||
保存组场景 = '/scene/saveByGroupId',
|
||||
@ -39,6 +40,20 @@ export async function saveSceneById(id: SceneInfo['id'], json: string): Promise<
|
||||
}
|
||||
}
|
||||
|
||||
export async function pushSceneById(id: SceneInfo['id']): Promise<boolean> {
|
||||
if (!id) return false;
|
||||
type B = { id: string };
|
||||
type D = void;
|
||||
try {
|
||||
const body = { id };
|
||||
await http.post<D, B>(API.推送场景, body);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.debug(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSceneByGroupId(
|
||||
id: RobotGroup['id'],
|
||||
sid: RobotGroup['sid'],
|
||||
|
@ -1,10 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { getSceneById } from '@api/scene';
|
||||
import { getSceneById, pushSceneById } from '@api/scene';
|
||||
import { EditorService } from '@core/editor.service';
|
||||
import { decodeTextFile, downloadFile, selectFile, textToBlob } from '@core/utils';
|
||||
import { Modal } from 'ant-design-vue';
|
||||
import { computed, watch } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { onMounted, provide, shallowRef } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const EDITOR_KEY = Symbol('editor-key');
|
||||
|
||||
@ -13,12 +15,18 @@ type Props = {
|
||||
};
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
//#region 接口
|
||||
const readScene = async () => {
|
||||
const res = await getSceneById(props.id);
|
||||
title.value = res?.label ?? '';
|
||||
editor.value?.load(res?.json, editable.value);
|
||||
};
|
||||
|
||||
const pushScene = async () => {
|
||||
await pushSceneById(props.id);
|
||||
};
|
||||
//#endregion
|
||||
|
||||
const title = ref<string>('');
|
||||
@ -38,6 +46,17 @@ onMounted(() => {
|
||||
const editable = ref<boolean>(false);
|
||||
watch(editable, (v) => editor.value?.setState(v));
|
||||
|
||||
const toPush = () =>
|
||||
Modal.confirm({
|
||||
class: 'confirm',
|
||||
title: t('您确定要推送该场景文件至数据库吗?'),
|
||||
content: t('请确保当前场景已经保存,否则可能导致推送的文件版本不正确。'),
|
||||
centered: true,
|
||||
cancelText: t('返回'),
|
||||
okText: t('推送'),
|
||||
onOk: () => pushScene(),
|
||||
});
|
||||
|
||||
const importScene = async () => {
|
||||
const file = await selectFile('.scene');
|
||||
if (!file?.size) return;
|
||||
@ -93,6 +112,7 @@ const selectRobot = (id: string) => {
|
||||
<i class="icon edit size-18 mr-8" />
|
||||
<span>{{ $t('启用编辑器') }}</span>
|
||||
</a-button>
|
||||
<a-button @click="toPush">{{ $t('同步') }}</a-button>
|
||||
<a-button @click="importScene">{{ $t('导入') }}</a-button>
|
||||
<a-button @click="exportScene">{{ $t('导出') }}</a-button>
|
||||
</a-space>
|
||||
|
@ -35,13 +35,14 @@ export class EditorService extends Meta2d {
|
||||
scene.robots = detail.robots;
|
||||
}
|
||||
const { robotGroups, robots, points, routes, areas } = scene;
|
||||
this.open(undefined, false);
|
||||
await this.#loadScenePoints(points);
|
||||
const data = this.data();
|
||||
data.robotGroups = robotGroups;
|
||||
data.robots = robots;
|
||||
this.open(data, true);
|
||||
this.open();
|
||||
this.setState(editable);
|
||||
this.#loadRobots(robotGroups, robots);
|
||||
await this.#loadScenePoints(points);
|
||||
this.#loadSceneRoutes(routes);
|
||||
await this.#loadSceneAreas(areas);
|
||||
this.store.historyIndex = undefined;
|
||||
this.store.histories = [];
|
||||
}
|
||||
public save(): string {
|
||||
const scene: StandardScene = {
|
||||
@ -55,6 +56,11 @@ export class EditorService extends Meta2d {
|
||||
return JSON.stringify(scene);
|
||||
}
|
||||
|
||||
#loadRobots(groups?: RobotGroup[], robots?: RobotInfo[]): void {
|
||||
this.#robotMap.clear();
|
||||
robots?.forEach((v) => this.#robotMap.set(v.id, v));
|
||||
this.#robotGroups$$.next(groups ?? []);
|
||||
}
|
||||
async #loadScenePoints(points?: StandardScenePoint[]): Promise<void> {
|
||||
if (!points?.length) return;
|
||||
await Promise.all(
|
||||
@ -68,6 +74,31 @@ export class EditorService extends Meta2d {
|
||||
}),
|
||||
);
|
||||
}
|
||||
#loadSceneRoutes(routes?: StandardSceneRoute[]): void {
|
||||
if (!routes?.length) return;
|
||||
routes.map((v) => {
|
||||
const { id, desc, from, to, type, pass, c1, c2, properties } = v;
|
||||
this.addRoute([from, to], <MapRouteType>type, id);
|
||||
this.setValue(
|
||||
{ id, desc, properties, route: { type, pass, c1, c2 } },
|
||||
{ render: false, history: false, doEvent: false },
|
||||
);
|
||||
});
|
||||
}
|
||||
async #loadSceneAreas(areas?: StandardSceneArea[]): Promise<void> {
|
||||
if (!areas?.length) return;
|
||||
await Promise.all(
|
||||
areas.map(async (v) => {
|
||||
const { id, name, desc, x, y, w, h, type, points, routes, properties } = v;
|
||||
await this.addArea({ x, y }, { x: x + w, y: y + h }, type, id);
|
||||
this.setValue(
|
||||
{ id, label: name, desc, properties, area: { type, points, routes } },
|
||||
{ render: false, history: false, doEvent: false },
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#mapScenePoint(pen?: MapPen): StandardScenePoint | null {
|
||||
if (!pen?.id || isEmpty(pen?.point)) return null;
|
||||
const { id, label, desc, properties } = pen;
|
||||
@ -433,23 +464,26 @@ export class EditorService extends Meta2d {
|
||||
const w = Math.abs(p1.x - p2.x);
|
||||
const h = Math.abs(p1.y - p2.y);
|
||||
if (w * scale < 50 || h * scale < 60) return;
|
||||
const selected = <MapPen[]>this.store.active;
|
||||
id ||= s8();
|
||||
const points = new Array<string>();
|
||||
const routes = new Array<string>();
|
||||
switch (type) {
|
||||
case MapAreaType.库区:
|
||||
selected?.filter(({ point }) => point?.type === MapPointType.动作点).forEach(({ id }) => points.push(id!));
|
||||
break;
|
||||
case MapAreaType.互斥区:
|
||||
selected?.filter(({ point }) => point?.type).forEach(({ id }) => points.push(id!));
|
||||
selected?.filter(({ route }) => route?.type).forEach(({ id }) => routes.push(id!));
|
||||
break;
|
||||
case MapAreaType.非互斥区:
|
||||
selected?.filter(({ point }) => point?.type).forEach(({ id }) => points.push(id!));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (id) {
|
||||
const selected = <MapPen[]>this.store.active;
|
||||
switch (type) {
|
||||
case MapAreaType.库区:
|
||||
selected?.filter(({ point }) => point?.type === MapPointType.动作点).forEach(({ id }) => points.push(id!));
|
||||
break;
|
||||
case MapAreaType.互斥区:
|
||||
selected?.filter(({ point }) => point?.type).forEach(({ id }) => points.push(id!));
|
||||
selected?.filter(({ route }) => route?.type).forEach(({ id }) => routes.push(id!));
|
||||
break;
|
||||
case MapAreaType.非互斥区:
|
||||
selected?.filter(({ point }) => point?.type).forEach(({ id }) => points.push(id!));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
id = s8();
|
||||
}
|
||||
const pen: MapPen = {
|
||||
id,
|
||||
@ -464,9 +498,8 @@ export class EditorService extends Meta2d {
|
||||
area: { type, points, routes },
|
||||
locked: LockState.DisableMoveScale,
|
||||
};
|
||||
const area = await this.addPen(pen, false, true, true);
|
||||
const area = await this.addPen(pen, true, true, true);
|
||||
this.bottom(area);
|
||||
// this.pushHistory({ type: EditType.Add, pens: [cloneDeep(pen)] });
|
||||
}
|
||||
|
||||
public updateArea(id: string, info: Partial<MapAreaInfo>): void {
|
||||
@ -493,12 +526,6 @@ export class EditorService extends Meta2d {
|
||||
|
||||
#load(theme: string): void {
|
||||
this.setTheme(theme);
|
||||
|
||||
const { robots, robotGroups } = this.data();
|
||||
this.#robotMap.clear();
|
||||
robots?.forEach((r) => this.#robotMap.set(r.id, r));
|
||||
this.#robotGroups$$.next(robotGroups ?? []);
|
||||
|
||||
this.find('point').forEach((pen) => {
|
||||
if (!pen.point?.type) return;
|
||||
if (pen.point.type < 10) return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user