refactor: 移除editor token,改为使用editorStore管理编辑器实例,优化机器人信息获取逻辑,提升代码可读性和维护性

This commit is contained in:
xudan 2025-09-11 15:42:27 +08:00
parent 96cbdf8b51
commit a346766b3d
6 changed files with 78 additions and 27 deletions

View File

@ -36,7 +36,6 @@
<RobotMenu
v-else-if="menuType === 'robot' && robotId"
:robot-id="robotId"
:token="token"
@action-complete="handleActionComplete"
@custom-image="handleCustomImage"
/>
@ -53,10 +52,9 @@
<script setup lang="ts">
import { message } from 'ant-design-vue';
import { computed, defineAsyncComponent, type InjectionKey, ref, type ShallowRef } from 'vue';
import { computed, defineAsyncComponent, ref } from 'vue';
import type { StorageLocationInfo } from '../../services/context-menu';
import type { EditorService } from '../../services/editor.service';
// 使 TypeScript
const DefaultMenu = defineAsyncComponent(() => import('./default-menu.vue'));
@ -70,7 +68,6 @@ interface Props {
menuType?: 'default' | 'storage' | 'storage-background' | 'robot' | 'point' | 'area';
storageLocations?: StorageLocationInfo[];
robotId?: string; // ID
token?: InjectionKey<ShallowRef<EditorService>>; // editor token
apiBaseUrl?: string;
}

View File

@ -126,7 +126,7 @@
<script setup lang="ts">
import { message } from 'ant-design-vue';
import { computed, inject, type InjectionKey, ref, type ShallowRef } from 'vue';
import { computed, ref } from 'vue';
import type { RobotInfo } from '../../apis/robot';
import type { RobotAction } from '../../services/context-menu/robot-menu.service';
@ -135,12 +135,11 @@ import {
getRobotStatusColor,
getRobotStatusText
} from '../../services/context-menu/robot-menu.service';
import type { EditorService } from '../../services/editor.service';
import { editorStore } from '../../stores/editor.store';
import RobotImageSettingsModal from '../modal/robot-image-settings-modal.vue';
interface Props {
robotId?: string; // ID
token?: InjectionKey<ShallowRef<EditorService>>; // editor token
}
interface Emits {
@ -152,13 +151,10 @@ const props = defineProps<Props>();
const emit = defineEmits<Emits>();
// editor service
const editor = props.token ? inject(props.token) : null;
// robotId
const robotInfo = computed<RobotInfo | null>(() => {
if (!props.robotId || !editor?.value) return null;
return editor.value.getRobotById(props.robotId) || null;
if (!props.robotId || !editorStore.hasEditor()) return null;
return editorStore.getEditorValue()?.getRobotById(props.robotId) || null;
});
//

View File

@ -76,7 +76,7 @@ import { message } from 'ant-design-vue';
import { computed, onMounted, ref, watch } from 'vue';
import colorConfig from '../../services/color/color-config.service';
import { EditorService } from '../../services/editor.service';
import { editorStore } from '../../stores/editor.store';
interface RobotInfo {
name: string;
@ -88,7 +88,6 @@ interface Props {
open: boolean;
robots: RobotInfo[];
selectedRobotName?: string;
editor?: EditorService; // editorprops
}
interface Emits {
@ -119,7 +118,7 @@ const formData = ref({
});
//
const editor = computed(() => props.editor);
const editor = computed(() => editorStore.getEditorValue());
//
const availableRobots = computed(() => props.robots);

View File

@ -2,7 +2,7 @@
import { LockState } from '@meta2d/core';
import { message } from 'ant-design-vue';
import { isNil } from 'lodash-es';
import { computed, onMounted, onUnmounted, provide, ref, shallowRef, watch } from 'vue';
import { computed, onMounted, onUnmounted, provide, ref, type ShallowRef, shallowRef, watch } from 'vue';
import { useRoute } from 'vue-router';
import type { RobotRealtimeInfo } from '../apis/robot';
@ -15,6 +15,7 @@ import {
import { EditorService } from '../services/editor.service';
import { StorageLocationService } from '../services/storage-location.service';
import { useViewState } from '../services/useViewState';
import { editorStore } from '../stores/editor.store';
const EDITOR_KEY = Symbol('editor-key');
@ -215,6 +216,10 @@ const monitorScene = async () => {
//#region
onMounted(() => {
editor.value = new EditorService(container.value!);
// editor store
editorStore.setEditor(editor as ShallowRef<EditorService>);
storageLocationService.value = new StorageLocationService(editor.value, props.sid);
});
//#endregion
@ -345,9 +350,9 @@ const contextMenuState = ref<ContextMenuState>(contextMenuManager.getState());
//#endregion
// iframe
const backToCards = () => {
window.parent?.postMessage({ type: 'scene_return_to_cards' }, '*');
};
// const backToCards = () => {
// window.parent?.postMessage({ type: 'scene_return_to_cards' }, '*');
// };
//#region
/**

View File

@ -1,17 +1,15 @@
<script setup lang="ts">
import { message, Modal } from 'ant-design-vue';
import { computed, watch } from 'vue';
import { ref } from 'vue';
import { onMounted, provide, shallowRef } from 'vue';
import { computed, onMounted, provide, ref, type ShallowRef, shallowRef, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import type { MapPen } from '../apis/map';
import { getSceneById, pushSceneById, saveSceneById } from '../apis/scene';
import BatchEditToolbar from '../components/batch-edit-toolbar.vue';
import AutoCreateStorageModal from '../components/modal/auto-create-storage-modal.vue';
import { EditorService } from '../services/editor.service';
import { useViewState } from '../services/useViewState';
import { decodeTextFile, downloadFile, selectFile, textToBlob } from '../services/utils';
import { editorStore } from '../stores/editor.store';
const EDITOR_KEY = Symbol('editor-key');
@ -88,6 +86,9 @@ const autoCreateStorageData = ref<{
onMounted(() => {
editor.value = new EditorService(container.value!);
// editor store
editorStore.setEditor(editor as ShallowRef<EditorService>);
//
editor.value?.on('autoCreateStorageDialog', (data: any) => {
autoCreateStorageData.value = data;
@ -178,10 +179,10 @@ const handleAutoSaveAndRestoreViewState = async () => {
await autoSaveAndRestoreViewState(editor.value, props.id);
};
// iframe
const backToCards = () => {
window.parent?.postMessage({ type: 'scene_return_to_cards' }, '*');
};
// // iframe
// const backToCards = () => {
// window.parent?.postMessage({ type: 'scene_return_to_cards' }, '*');
// };
//
const handleAutoCreateStorageConfirm = (actionPoints: any[]) => {

View File

@ -0,0 +1,53 @@
import type { ShallowRef } from 'vue';
import type { EditorService } from '../services/editor.service';
/**
* Editor Store
*
*/
class EditorStore {
private _editor: ShallowRef<EditorService> | null = null;
/**
*
*/
get editor(): ShallowRef<EditorService> | null {
return this._editor;
}
/**
*
* @param editor
*/
setEditor(editor: ShallowRef<EditorService>): void {
this._editor = editor;
}
/**
*
*/
clearEditor(): void {
this._editor = null;
}
/**
*
*/
hasEditor(): boolean {
return this._editor !== null && this._editor.value !== undefined;
}
/**
*
*/
getEditorValue(): EditorService | null {
return this._editor?.value || null;
}
}
// 创建单例实例
export const editorStore = new EditorStore();
// 导出类型
export type { EditorService };