@jnrs/lingshu-smart 2.2.6 → 2.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.vue.d.ts +2 -1
- package/dist/App.vue.js +30 -0
- package/dist/assets/data/editor_default.d.ts +8 -1
- package/dist/assets/data/editor_default.js +59 -0
- package/dist/assets/data/editor_default_setting.d.ts +16 -0
- package/dist/assets/data/editor_default_setting.js +58 -0
- package/dist/assets/data/editor_preset.d.ts +8 -1
- package/dist/assets/data/editor_preset.js +51 -0
- package/dist/assets/data/editor_preset_menu.d.ts +9 -0
- package/dist/assets/data/editor_preset_menu.js +290 -0
- package/dist/components/editor/ControlBar/CaseManger.vue.d.ts +3 -15
- package/dist/components/editor/ControlBar/CaseManger.vue.js +465 -0
- package/dist/components/editor/ControlBar/CaseTitleEdit.vue.d.ts +2 -411
- package/dist/components/editor/ControlBar/CaseTitleEdit.vue.js +108 -0
- package/dist/components/editor/ControlBar/ExportImportDialog.vue.d.ts +3 -2
- package/dist/components/editor/ControlBar/ExportImportDialog.vue.js +280 -0
- package/dist/components/editor/ControlBar/MainButton.vue.d.ts +3 -2
- package/dist/components/editor/ControlBar/MainButton.vue.js +183 -0
- package/dist/components/editor/ControlBar/StepButton.vue.d.ts +2 -1
- package/dist/components/editor/ControlBar/StepButton.vue.js +147 -0
- package/dist/components/editor/ControlBar/StepRecordVisualizer.vue.d.ts +2 -1
- package/dist/components/editor/ControlBar/StepRecordVisualizer.vue.js +98 -0
- package/dist/components/editor/DrawingBoard.vue.d.ts +2 -1
- package/dist/components/editor/DrawingBoard.vue.js +31 -0
- package/dist/components/editor/MenuCard/Equipments.vue.d.ts +2 -1
- package/dist/components/editor/MenuCard/Equipments.vue.js +129 -0
- package/dist/components/editor/MenuCard/Layers.vue.d.ts +2 -1
- package/dist/components/editor/MenuCard/Layers.vue.js +201 -0
- package/dist/components/editor/MenuCard/index.vue.d.ts +2 -1
- package/dist/components/editor/MenuCard/index.vue.js +84 -0
- package/dist/components/editor/OptionCard/Equipment/Base.vue.d.ts +2 -1
- package/dist/components/editor/OptionCard/Equipment/Base.vue.js +96 -0
- package/dist/components/editor/OptionCard/Equipment/Binds.vue.d.ts +3 -0
- package/dist/components/editor/OptionCard/Equipment/Binds.vue.js +443 -0
- package/dist/components/editor/OptionCard/Equipment/Bot.vue.d.ts +3 -0
- package/dist/components/editor/OptionCard/Equipment/Bot.vue.js +81 -0
- package/dist/components/editor/OptionCard/Equipment/DataSets.vue.d.ts +2 -1
- package/dist/components/editor/OptionCard/Equipment/DataSets.vue.js +304 -0
- package/dist/components/editor/OptionCard/Equipment/DockStore.vue.d.ts +3 -0
- package/dist/components/editor/OptionCard/Equipment/DockStore.vue.js +597 -0
- package/dist/components/editor/OptionCard/Equipment/Interaction.vue.d.ts +2 -1
- package/dist/components/editor/OptionCard/Equipment/Interaction.vue.js +287 -0
- package/dist/components/editor/OptionCard/Equipment/Position.backup.vue.d.ts +3 -0
- package/dist/components/editor/OptionCard/Equipment/Position.backup.vue.js +440 -0
- package/dist/components/editor/OptionCard/Equipment/Position.vue.d.ts +2 -1
- package/dist/components/editor/OptionCard/Equipment/Position.vue.js +436 -0
- package/dist/components/editor/OptionCard/Equipment/StationSlotGroup.vue.d.ts +2 -1
- package/dist/components/editor/OptionCard/Equipment/StationSlotGroup.vue.js +1131 -0
- package/dist/components/editor/OptionCard/Equipment/Store.vue.d.ts +3 -0
- package/dist/components/editor/OptionCard/Equipment/Store.vue.js +453 -0
- package/dist/components/editor/OptionCard/Equipment/Trailer.vue.d.ts +3 -0
- package/dist/components/editor/OptionCard/Equipment/Trailer.vue.js +1109 -0
- package/dist/components/editor/OptionCard/Equipment/index.vue.d.ts +2 -1
- package/dist/components/editor/OptionCard/Equipment/index.vue.js +100 -0
- package/dist/components/editor/OptionCard/Equipment/models/MachineTool.vue.d.ts +3 -0
- package/dist/components/editor/OptionCard/Equipment/models/MachineTool.vue.js +99 -0
- package/dist/components/editor/OptionCard/Equipment/models/Rail.vue.d.ts +3 -0
- package/dist/components/editor/OptionCard/Equipment/models/Rail.vue.js +225 -0
- package/dist/components/editor/OptionCard/Equipment/models/SingleGripperRobot.vue.d.ts +3 -0
- package/dist/components/editor/OptionCard/Equipment/models/SingleGripperRobot.vue.js +99 -0
- package/dist/components/editor/OptionCard/Scene/Background.vue.d.ts +2 -1
- package/dist/components/editor/OptionCard/Scene/Background.vue.js +543 -0
- package/dist/components/editor/OptionCard/Scene/index.vue.d.ts +2 -1
- package/dist/components/editor/OptionCard/Scene/index.vue.js +200 -0
- package/dist/components/editor/OptionCard/index.vue.d.ts +2 -1
- package/dist/components/editor/OptionCard/index.vue.js +73 -0
- package/dist/components/editor/index.vue.d.ts +4 -13
- package/dist/components/editor/index.vue.js +156 -0
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +4 -25440
- package/dist/components/preview/index.vue.d.ts +6 -5
- package/dist/components/preview/index.vue.js +104 -0
- package/dist/composables/useStepRecord.d.ts +12 -4
- package/dist/composables/useStepRecord.js +135 -0
- package/dist/constants/options.d.ts +8 -1
- package/dist/constants/options.js +55 -0
- package/dist/controller/AppController.d.ts +10 -3
- package/dist/controller/AppController.js +168 -0
- package/dist/controller/EditorController.d.ts +9 -2
- package/dist/controller/EditorController.js +173 -0
- package/dist/index.js +1 -1
- package/dist/locales/en.js +5 -0
- package/dist/locales/i18next.d.ts +1 -1
- package/dist/locales/i18next.js +6 -0
- package/dist/locales/index.d.ts +2 -2
- package/dist/locales/index.js +3 -13
- package/dist/locales/zhCn.js +5 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.js +13 -0
- package/dist/playground/EditPageDemo.vue.d.ts +2 -1
- package/dist/playground/EditPageDemo.vue.js +57 -0
- package/dist/playground/ViewPageDemo.vue.d.ts +2 -27
- package/dist/playground/ViewPageDemo.vue.js +277 -0
- package/dist/stores/index.js +3 -0
- package/dist/stores/useAppStore.d.ts +13 -6
- package/dist/stores/useAppStore.js +78 -0
- package/dist/stores/useDataStore.d.ts +18 -11
- package/dist/stores/useDataStore.js +116 -0
- package/dist/stores/useEditorStore.d.ts +27 -20
- package/dist/stores/useEditorStore.js +263 -0
- package/dist/types/app.types.d.ts +1 -1
- package/dist/types/app.types.js +2 -0
- package/dist/types/base.types.d.ts +4 -2
- package/dist/types/base.types.js +1 -0
- package/dist/types/components/config.types.d.ts +11 -3
- package/dist/types/components/config.types.js +1 -0
- package/dist/types/components/operating.types.d.ts +1 -1
- package/dist/types/components/operating.types.js +1 -0
- package/dist/types/enums.d.ts +5 -2
- package/dist/types/enums.js +46 -0
- package/dist/types/guards.d.ts +12 -2
- package/dist/types/guards.js +28 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +8 -0
- package/dist/types/models/config.types.d.ts +74 -29
- package/dist/types/models/config.types.js +1 -0
- package/dist/types/models/operating.types.d.ts +83 -17
- package/dist/types/models/operating.types.js +1 -0
- package/dist/ui/abstract/ComponentAbs.d.ts +9 -2
- package/dist/ui/abstract/ComponentAbs.js +64 -0
- package/dist/ui/abstract/ModelAbs.d.ts +12 -2
- package/dist/ui/abstract/ModelAbs.js +119 -0
- package/dist/ui/components/Entrance.d.ts +8 -1
- package/dist/ui/components/Entrance.js +83 -0
- package/dist/ui/components/Light.d.ts +26 -3
- package/dist/ui/components/Light.js +167 -0
- package/dist/ui/components/Progress.d.ts +8 -1
- package/dist/ui/components/Progress.js +84 -0
- package/dist/ui/components/Resource.d.ts +8 -1
- package/dist/ui/components/Resource.js +70 -0
- package/dist/ui/components/StationSlot.d.ts +24 -2
- package/dist/ui/components/StationSlot.js +207 -0
- package/dist/ui/components/StationSlotGroup.d.ts +8 -1
- package/dist/ui/components/StationSlotGroup.js +110 -0
- package/dist/ui/factories/createGlass.d.ts +9 -1
- package/dist/ui/factories/createGlass.js +51 -0
- package/dist/ui/factories/createModel.d.ts +9 -2
- package/dist/ui/factories/createModel.js +35 -0
- package/dist/ui/factories/createShadow.d.ts +12 -4
- package/dist/ui/factories/createShadow.js +52 -0
- package/dist/ui/factories/createText.d.ts +7 -0
- package/dist/ui/factories/createText.js +46 -0
- package/dist/ui/models/CleaningMachine.d.ts +14 -0
- package/dist/ui/models/CleaningMachine.js +141 -0
- package/dist/ui/models/DoubleJointRobot.d.ts +23 -0
- package/dist/ui/models/DoubleJointRobot.js +545 -0
- package/dist/ui/models/LoadingStation.d.ts +16 -0
- package/dist/ui/models/LoadingStation.js +167 -0
- package/dist/ui/models/MachineTool.d.ts +5 -4
- package/dist/ui/models/MachineTool.js +184 -0
- package/dist/ui/models/MarkingMachine.d.ts +16 -0
- package/dist/ui/models/MarkingMachine.js +148 -0
- package/dist/ui/models/Rail.d.ts +15 -0
- package/dist/ui/models/Rail.js +117 -0
- package/dist/ui/models/ResourceStore.d.ts +12 -0
- package/dist/ui/models/ResourceStore.js +101 -0
- package/dist/ui/models/SingleBot.d.ts +20 -0
- package/dist/ui/models/SingleBot.js +202 -0
- package/dist/ui/models/SingleGripperRobot.d.ts +19 -0
- package/dist/ui/models/SingleGripperRobot.js +272 -0
- package/dist/ui/models/SingleJointRobot.d.ts +22 -0
- package/dist/ui/models/SingleJointRobot.js +346 -0
- package/dist/ui/shapes/NamePlate.d.ts +10 -1
- package/dist/ui/shapes/NamePlate.js +85 -0
- package/dist/ui/shapes/ScrewHole.d.ts +8 -1
- package/dist/ui/shapes/ScrewHole.js +57 -0
- package/dist/ui/shapes/Texture.d.ts +12 -3
- package/dist/ui/shapes/Texture.js +51 -0
- package/dist/ui/utils/attr.d.ts +10 -3
- package/dist/ui/utils/attr.js +50 -0
- package/dist/utils/index.js +92 -0
- package/dist/utils/type-guards.d.ts +1 -1
- package/dist/utils/type-guards.js +105 -0
- package/package.json +2 -2
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author : TanRui
|
|
3
|
+
* @WeChat : Tan578853789
|
|
4
|
+
* @File : useAppStore.ts
|
|
5
|
+
* @Date : 2026/03/20
|
|
6
|
+
* @Desc. : 用于预览页面:当前方案状态
|
|
7
|
+
*/
|
|
8
|
+
import { defineStore } from 'pinia';
|
|
9
|
+
import { ref } from 'vue';
|
|
10
|
+
import { AppController } from '@/controller/AppController';
|
|
11
|
+
import { useDataStore } from './useDataStore';
|
|
12
|
+
export const useAppStore = defineStore('@jnrs/lingshu-smart/app', () => {
|
|
13
|
+
const sharedStore = useDataStore();
|
|
14
|
+
const currentCase = ref();
|
|
15
|
+
// 容器实例
|
|
16
|
+
let appContainer = null;
|
|
17
|
+
/**
|
|
18
|
+
* 初始化容器(引擎实例)
|
|
19
|
+
* @param options 容器配置
|
|
20
|
+
* @param caseUuid 当前方案 UUID
|
|
21
|
+
*/
|
|
22
|
+
const initContainer = (options, caseUuid) => {
|
|
23
|
+
if (appContainer) {
|
|
24
|
+
console.warn('❌ Container already initialized');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
appContainer = new AppController(options);
|
|
28
|
+
console.log('✅ AppController Initialized');
|
|
29
|
+
currentCase.value = sharedStore.cases?.find((c) => c.uuid === caseUuid);
|
|
30
|
+
if (currentCase.value) {
|
|
31
|
+
for (const layer of currentCase.value.layers) {
|
|
32
|
+
appContainer.addModel(layer);
|
|
33
|
+
}
|
|
34
|
+
appContainer.setTree(currentCase.value.scene);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.warn('⚠️ 当前方案不存在', { cases: sharedStore.cases }, { caseUuid });
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* resize 容器
|
|
42
|
+
*/
|
|
43
|
+
const resizeContainer = () => {
|
|
44
|
+
if (!appContainer) {
|
|
45
|
+
console.warn('❌ resizeContainer failed: AppController not initialized');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
appContainer.setZoom();
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* 销毁容器
|
|
52
|
+
*/
|
|
53
|
+
const destroyContainer = () => {
|
|
54
|
+
if (!appContainer) {
|
|
55
|
+
console.warn('❌ destroyContainer failed: AppController not initialized');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
appContainer.destroy();
|
|
59
|
+
appContainer = null;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* 设备运转
|
|
63
|
+
*/
|
|
64
|
+
const operating = (data) => {
|
|
65
|
+
if (!appContainer) {
|
|
66
|
+
console.warn('❌ operating failed: AppController not initialized');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
appContainer.operating(data);
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
currentCase,
|
|
73
|
+
initContainer,
|
|
74
|
+
resizeContainer,
|
|
75
|
+
destroyContainer,
|
|
76
|
+
operating
|
|
77
|
+
};
|
|
78
|
+
});
|
|
@@ -1,26 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @Author : TanRui
|
|
3
|
+
* @WeChat : Tan578853789
|
|
4
|
+
* @File : useDataStore.ts
|
|
5
|
+
* @Date : 2026/03/23
|
|
6
|
+
* @Desc. : 设备列表、方案列表、当前方案、当前方案的场景、当前方案的图层列表、当前图层状态管理
|
|
7
|
+
*/
|
|
8
|
+
import type { ICase } from '@/types';
|
|
9
|
+
export declare const useDataStore: import("pinia").StoreDefinition<"@jnrs/lingshu-smart/data", Pick<{
|
|
10
|
+
casesLoading: import("vue").Ref<boolean, boolean>;
|
|
11
|
+
equipmentsMenu: import("@/types").IEquipmentsMenu[];
|
|
12
|
+
cases: import("vue").Ref<ICase[] | undefined, ICase[] | undefined>;
|
|
6
13
|
updateCases: (data?: ICase[]) => void;
|
|
7
14
|
selectCase: (uuid: string) => void;
|
|
8
15
|
addCase: (data?: ICase) => void;
|
|
9
16
|
removeCase: (uuid: string) => void;
|
|
10
17
|
clearCases: () => void;
|
|
11
18
|
}, "cases" | "casesLoading" | "equipmentsMenu">, Pick<{
|
|
12
|
-
casesLoading: import(
|
|
13
|
-
equipmentsMenu: import(
|
|
14
|
-
cases: import(
|
|
19
|
+
casesLoading: import("vue").Ref<boolean, boolean>;
|
|
20
|
+
equipmentsMenu: import("@/types").IEquipmentsMenu[];
|
|
21
|
+
cases: import("vue").Ref<ICase[] | undefined, ICase[] | undefined>;
|
|
15
22
|
updateCases: (data?: ICase[]) => void;
|
|
16
23
|
selectCase: (uuid: string) => void;
|
|
17
24
|
addCase: (data?: ICase) => void;
|
|
18
25
|
removeCase: (uuid: string) => void;
|
|
19
26
|
clearCases: () => void;
|
|
20
27
|
}, never>, Pick<{
|
|
21
|
-
casesLoading: import(
|
|
22
|
-
equipmentsMenu: import(
|
|
23
|
-
cases: import(
|
|
28
|
+
casesLoading: import("vue").Ref<boolean, boolean>;
|
|
29
|
+
equipmentsMenu: import("@/types").IEquipmentsMenu[];
|
|
30
|
+
cases: import("vue").Ref<ICase[] | undefined, ICase[] | undefined>;
|
|
24
31
|
updateCases: (data?: ICase[]) => void;
|
|
25
32
|
selectCase: (uuid: string) => void;
|
|
26
33
|
addCase: (data?: ICase) => void;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author : TanRui
|
|
3
|
+
* @WeChat : Tan578853789
|
|
4
|
+
* @File : useDataStore.ts
|
|
5
|
+
* @Date : 2026/03/23
|
|
6
|
+
* @Desc. : 设备列表、方案列表、当前方案、当前方案的场景、当前方案的图层列表、当前图层状态管理
|
|
7
|
+
*/
|
|
8
|
+
import { ref } from 'vue';
|
|
9
|
+
import { defineStore } from 'pinia';
|
|
10
|
+
import { isICaseArray, isICase } from '@/utils/type-guards';
|
|
11
|
+
import { uuidv4 } from '@jnrs/shared/uuid';
|
|
12
|
+
import { cloneDeep } from '@jnrs/shared/lodash';
|
|
13
|
+
import { CASE_INIT } from '@/constants/options';
|
|
14
|
+
import { EQUIPMENTS_MENU } from '@/assets/data/editor_preset_menu';
|
|
15
|
+
export const useDataStore = defineStore('@jnrs/lingshu-smart/data', () => {
|
|
16
|
+
// 设备菜单
|
|
17
|
+
const equipmentsMenu = cloneDeep(EQUIPMENTS_MENU);
|
|
18
|
+
// 方案列表
|
|
19
|
+
const cases = ref();
|
|
20
|
+
const casesLoading = ref(false);
|
|
21
|
+
/**
|
|
22
|
+
* 更新方案列表
|
|
23
|
+
*/
|
|
24
|
+
const updateCases = (data) => {
|
|
25
|
+
if (!data) {
|
|
26
|
+
cases.value = [];
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// 类型守卫:校验数据结构
|
|
30
|
+
if (isICaseArray(data)) {
|
|
31
|
+
cases.value = data;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const errorMsg = '运行 updateCases 函数时参数校验失败:发现非法的 ICase, ILayer 或 IScene 结构';
|
|
35
|
+
console.error(errorMsg, data);
|
|
36
|
+
throw new Error(errorMsg);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* 切换当前方案
|
|
41
|
+
*/
|
|
42
|
+
const selectCase = (uuid) => {
|
|
43
|
+
if (!cases.value)
|
|
44
|
+
return;
|
|
45
|
+
const target = cases.value.find((c) => c.uuid === uuid);
|
|
46
|
+
if (!target)
|
|
47
|
+
return;
|
|
48
|
+
cases.value.forEach((c) => {
|
|
49
|
+
c.isActive = c.uuid === uuid;
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* 添加方案
|
|
54
|
+
*/
|
|
55
|
+
const addCase = (data) => {
|
|
56
|
+
// 如果方案列表不存在,则初始化
|
|
57
|
+
if (!cases.value) {
|
|
58
|
+
cases.value = [];
|
|
59
|
+
}
|
|
60
|
+
const uuid = uuidv4();
|
|
61
|
+
if (data) {
|
|
62
|
+
// 类型守卫:校验数据结构
|
|
63
|
+
if (isICase(data)) {
|
|
64
|
+
const newCase = cloneDeep(data);
|
|
65
|
+
newCase.uuid = uuid; // 重置方案 uuid 防止冲突
|
|
66
|
+
newCase.isActive = false; // 重置方案 isActive 状态防止冲突
|
|
67
|
+
cases.value.push(newCase);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const errorMsg = '运行 addCase 函数时参数校验失败:发现非法的 ICase, ILayer 或 IScene 结构';
|
|
71
|
+
console.error(errorMsg, data);
|
|
72
|
+
throw new Error(errorMsg);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const newCase = cloneDeep(CASE_INIT);
|
|
77
|
+
newCase.uuid = uuid;
|
|
78
|
+
newCase.title = `方案${uuid.slice(0, 8)}`;
|
|
79
|
+
cases.value.push(newCase);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* 删除方案
|
|
84
|
+
*/
|
|
85
|
+
const removeCase = (uuid) => {
|
|
86
|
+
if (!cases.value)
|
|
87
|
+
return;
|
|
88
|
+
const index = cases.value.findIndex((c) => c.uuid === uuid);
|
|
89
|
+
if (index === -1)
|
|
90
|
+
return;
|
|
91
|
+
cases.value.splice(index, 1);
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* 清空方案列表
|
|
95
|
+
*/
|
|
96
|
+
const clearCases = () => {
|
|
97
|
+
cases.value = [];
|
|
98
|
+
};
|
|
99
|
+
return {
|
|
100
|
+
// getters
|
|
101
|
+
casesLoading,
|
|
102
|
+
equipmentsMenu,
|
|
103
|
+
cases,
|
|
104
|
+
// actions
|
|
105
|
+
updateCases,
|
|
106
|
+
selectCase,
|
|
107
|
+
addCase,
|
|
108
|
+
removeCase,
|
|
109
|
+
clearCases
|
|
110
|
+
};
|
|
111
|
+
}, {
|
|
112
|
+
persist: {
|
|
113
|
+
storage: localStorage,
|
|
114
|
+
pick: ['cases']
|
|
115
|
+
}
|
|
116
|
+
});
|
|
@@ -1,44 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @Author : TanRui
|
|
3
|
+
* @WeChat : Tan578853789
|
|
4
|
+
* @File : useEditorStore.ts
|
|
5
|
+
* @Date : 2026/01/21
|
|
6
|
+
* @Desc. : 用于编辑器页面:设备列表、方案列表、当前方案、当前方案的场景、当前方案的图层列表、当前图层状态管理
|
|
7
|
+
*/
|
|
8
|
+
import type { ICase, IScene, ILayer, IContainer } from '@/types';
|
|
9
|
+
export declare const useEditorStore: import("pinia").StoreDefinition<"@jnrs/lingshu-smart/editor", Pick<{
|
|
10
|
+
currentCase: import("vue").ComputedRef<ICase | null>;
|
|
11
|
+
scene: import("vue").ComputedRef<IScene | null>;
|
|
12
|
+
layers: import("vue").ComputedRef<ILayer[]>;
|
|
13
|
+
currentLayer: import("vue").ComputedRef<ILayer | null>;
|
|
7
14
|
initContainer: (options: IContainer) => void;
|
|
8
15
|
resizeContainer: () => void;
|
|
9
16
|
destroyContainer: () => void;
|
|
10
17
|
initEditor: () => void;
|
|
11
|
-
updateScene: import(
|
|
18
|
+
updateScene: import("@jnrs/shared/lodash").DebouncedFunc<() => void>;
|
|
12
19
|
addLayer: (layer: ILayer) => void;
|
|
13
20
|
selectLayer: (uuid?: string) => void;
|
|
14
21
|
updateLayer: (layer: ILayer) => void;
|
|
15
|
-
renderLayers: import(
|
|
22
|
+
renderLayers: import("@jnrs/shared/lodash").DebouncedFunc<() => void>;
|
|
16
23
|
}, never>, Pick<{
|
|
17
|
-
currentCase: import(
|
|
18
|
-
scene: import(
|
|
19
|
-
layers: import(
|
|
20
|
-
currentLayer: import(
|
|
24
|
+
currentCase: import("vue").ComputedRef<ICase | null>;
|
|
25
|
+
scene: import("vue").ComputedRef<IScene | null>;
|
|
26
|
+
layers: import("vue").ComputedRef<ILayer[]>;
|
|
27
|
+
currentLayer: import("vue").ComputedRef<ILayer | null>;
|
|
21
28
|
initContainer: (options: IContainer) => void;
|
|
22
29
|
resizeContainer: () => void;
|
|
23
30
|
destroyContainer: () => void;
|
|
24
31
|
initEditor: () => void;
|
|
25
|
-
updateScene: import(
|
|
32
|
+
updateScene: import("@jnrs/shared/lodash").DebouncedFunc<() => void>;
|
|
26
33
|
addLayer: (layer: ILayer) => void;
|
|
27
34
|
selectLayer: (uuid?: string) => void;
|
|
28
35
|
updateLayer: (layer: ILayer) => void;
|
|
29
|
-
renderLayers: import(
|
|
36
|
+
renderLayers: import("@jnrs/shared/lodash").DebouncedFunc<() => void>;
|
|
30
37
|
}, "currentCase" | "scene" | "layers" | "currentLayer">, Pick<{
|
|
31
|
-
currentCase: import(
|
|
32
|
-
scene: import(
|
|
33
|
-
layers: import(
|
|
34
|
-
currentLayer: import(
|
|
38
|
+
currentCase: import("vue").ComputedRef<ICase | null>;
|
|
39
|
+
scene: import("vue").ComputedRef<IScene | null>;
|
|
40
|
+
layers: import("vue").ComputedRef<ILayer[]>;
|
|
41
|
+
currentLayer: import("vue").ComputedRef<ILayer | null>;
|
|
35
42
|
initContainer: (options: IContainer) => void;
|
|
36
43
|
resizeContainer: () => void;
|
|
37
44
|
destroyContainer: () => void;
|
|
38
45
|
initEditor: () => void;
|
|
39
|
-
updateScene: import(
|
|
46
|
+
updateScene: import("@jnrs/shared/lodash").DebouncedFunc<() => void>;
|
|
40
47
|
addLayer: (layer: ILayer) => void;
|
|
41
48
|
selectLayer: (uuid?: string) => void;
|
|
42
49
|
updateLayer: (layer: ILayer) => void;
|
|
43
|
-
renderLayers: import(
|
|
50
|
+
renderLayers: import("@jnrs/shared/lodash").DebouncedFunc<() => void>;
|
|
44
51
|
}, "initContainer" | "resizeContainer" | "destroyContainer" | "initEditor" | "updateScene" | "addLayer" | "selectLayer" | "updateLayer" | "renderLayers">>;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Author : TanRui
|
|
3
|
+
* @WeChat : Tan578853789
|
|
4
|
+
* @File : useEditorStore.ts
|
|
5
|
+
* @Date : 2026/01/21
|
|
6
|
+
* @Desc. : 用于编辑器页面:设备列表、方案列表、当前方案、当前方案的场景、当前方案的图层列表、当前图层状态管理
|
|
7
|
+
*/
|
|
8
|
+
import { uuidv4 } from '@jnrs/shared/uuid';
|
|
9
|
+
import { debounce, cloneDeep } from '@jnrs/shared/lodash';
|
|
10
|
+
import { defineStore } from 'pinia';
|
|
11
|
+
import { computed, watch } from 'vue';
|
|
12
|
+
import { DEFAULT_LAYER } from '@/constants/options';
|
|
13
|
+
import { AppController } from '@/controller/AppController';
|
|
14
|
+
import { EditorController } from '@/controller/EditorController';
|
|
15
|
+
import { transPercentAndPixel } from '@/utils';
|
|
16
|
+
import { useDataStore } from './useDataStore';
|
|
17
|
+
export const useEditorStore = defineStore('@jnrs/lingshu-smart/editor', () => {
|
|
18
|
+
const sharedStore = useDataStore();
|
|
19
|
+
// APP 容器实例
|
|
20
|
+
let appContainer = null;
|
|
21
|
+
// 编辑器实例
|
|
22
|
+
let editorManager = null;
|
|
23
|
+
// 当前选择的方案
|
|
24
|
+
const currentCase = computed(() => {
|
|
25
|
+
return sharedStore.cases?.find((c) => c.isActive) || null;
|
|
26
|
+
});
|
|
27
|
+
// 当前方案场景
|
|
28
|
+
const scene = computed(() => {
|
|
29
|
+
if (!currentCase.value)
|
|
30
|
+
return null;
|
|
31
|
+
return currentCase.value.scene;
|
|
32
|
+
});
|
|
33
|
+
// 当前方案图层列表
|
|
34
|
+
const layers = computed(() => {
|
|
35
|
+
if (!currentCase.value)
|
|
36
|
+
return [];
|
|
37
|
+
return currentCase.value.layers;
|
|
38
|
+
});
|
|
39
|
+
// 当前选择的图层
|
|
40
|
+
const currentLayer = computed(() => {
|
|
41
|
+
if (!currentCase.value)
|
|
42
|
+
return null;
|
|
43
|
+
return layers.value.find((d) => d.selected) || null;
|
|
44
|
+
});
|
|
45
|
+
/**
|
|
46
|
+
* 初始化容器(引擎实例)
|
|
47
|
+
*/
|
|
48
|
+
const initContainer = (options) => {
|
|
49
|
+
if (appContainer) {
|
|
50
|
+
console.warn('❌ Container already initialized');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
appContainer = new AppController(options);
|
|
54
|
+
console.log('✅ AppController Initialized');
|
|
55
|
+
if (options.appEditable) {
|
|
56
|
+
initEditor();
|
|
57
|
+
}
|
|
58
|
+
updateScene();
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* 修改场景
|
|
62
|
+
*/
|
|
63
|
+
const updateScene = debounce(() => {
|
|
64
|
+
if (!appContainer) {
|
|
65
|
+
console.warn('❌ updateScene failed: AppController not initialized');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (scene.value) {
|
|
69
|
+
console.log('🖥 updateScene...');
|
|
70
|
+
appContainer.setTree(scene.value);
|
|
71
|
+
}
|
|
72
|
+
// 场景更新后重新渲染全部图层
|
|
73
|
+
renderLayers();
|
|
74
|
+
}, 300);
|
|
75
|
+
/**
|
|
76
|
+
* 渲染全部图层
|
|
77
|
+
*/
|
|
78
|
+
const renderLayers = debounce(() => {
|
|
79
|
+
if (!appContainer) {
|
|
80
|
+
console.warn('❌ renderLayers failed: AppController not initialized');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// 先清空所有图层
|
|
84
|
+
appContainer.clearAll();
|
|
85
|
+
// 如果当前方案存在,则渲染当前方案
|
|
86
|
+
if (currentCase.value) {
|
|
87
|
+
const uuid = currentLayer.value?.uuid;
|
|
88
|
+
for (const layer of layers.value) {
|
|
89
|
+
appContainer.addModel(layer);
|
|
90
|
+
if (editorManager && layer.uuid === uuid) {
|
|
91
|
+
editorManager.selectEquipment(`#${uuid}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// 如果当前方案不存在,则初始化容器 UI
|
|
97
|
+
appContainer.setTree(undefined);
|
|
98
|
+
}
|
|
99
|
+
console.log('🖌 renderLayers...');
|
|
100
|
+
}, 250);
|
|
101
|
+
/**
|
|
102
|
+
* 销毁容器
|
|
103
|
+
*/
|
|
104
|
+
const destroyContainer = () => {
|
|
105
|
+
if (appContainer) {
|
|
106
|
+
appContainer.destroy();
|
|
107
|
+
appContainer = null;
|
|
108
|
+
console.log('✅ AppController Destroyed');
|
|
109
|
+
}
|
|
110
|
+
if (editorManager) {
|
|
111
|
+
editorManager.destroy();
|
|
112
|
+
editorManager = null;
|
|
113
|
+
console.log('✅ EditorController Destroyed');
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* resize 容器
|
|
118
|
+
*/
|
|
119
|
+
const resizeContainer = () => {
|
|
120
|
+
if (!appContainer) {
|
|
121
|
+
console.error('Cannot resize Container: AppController missing');
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
appContainer.setZoom();
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* 初始化编辑器
|
|
128
|
+
*/
|
|
129
|
+
const initEditor = () => {
|
|
130
|
+
if (!appContainer) {
|
|
131
|
+
console.error('Cannot init Editor: AppController missing');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
editorManager = new EditorController({
|
|
135
|
+
container: appContainer,
|
|
136
|
+
onSelected: (ids) => {
|
|
137
|
+
const uuid = ids[0];
|
|
138
|
+
layers.value.forEach((layer) => {
|
|
139
|
+
if (layer.uuid === uuid) {
|
|
140
|
+
layer.selected = true;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
layer.selected = false;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
},
|
|
147
|
+
onRotate: (rotation) => {
|
|
148
|
+
const layer = currentLayer.value;
|
|
149
|
+
if (layer) {
|
|
150
|
+
layer.rotation = rotation;
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
onScale: (width) => {
|
|
154
|
+
const layer = currentLayer.value;
|
|
155
|
+
if (layer && layer.width && layer.height) {
|
|
156
|
+
layer.scale = Number((width / layer.width).toFixed(2));
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
onMove: (x, y) => {
|
|
160
|
+
const layer = currentLayer.value;
|
|
161
|
+
if (layer && layer.width && layer.height) {
|
|
162
|
+
layer.x = x;
|
|
163
|
+
layer.y = y;
|
|
164
|
+
layer.percentX = transPercentAndPixel(x, scene.value?.width, 3, true);
|
|
165
|
+
layer.percentY = transPercentAndPixel(y, scene.value?.height, 3, true);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
console.log('✅ EditorController Initialized');
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* 更新图层属性 (修改当前 UI 需要立即响应属性,如宽高、位置、旋转、缩放等)
|
|
173
|
+
*/
|
|
174
|
+
const updateLayer = (layer) => {
|
|
175
|
+
if (!appContainer)
|
|
176
|
+
return;
|
|
177
|
+
const model = appContainer.findOne(`#${layer.uuid}`);
|
|
178
|
+
if (model) {
|
|
179
|
+
model.set(layer);
|
|
180
|
+
console.log('🎨 updateLayer');
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* 单独重绘某个图层(重绘为了修改子 UI 的显示)
|
|
185
|
+
* @param layer 要重绘的图层对象
|
|
186
|
+
*/
|
|
187
|
+
const rerenderLayer = debounce((layer) => {
|
|
188
|
+
if (editorManager) {
|
|
189
|
+
console.log('♻️ rerenderLayer...');
|
|
190
|
+
editorManager.rerenderModel(layer);
|
|
191
|
+
}
|
|
192
|
+
}, 500);
|
|
193
|
+
/**
|
|
194
|
+
* 添加图层(图层)到当前方案
|
|
195
|
+
*/
|
|
196
|
+
const addLayer = (layer) => {
|
|
197
|
+
if (!currentCase.value) {
|
|
198
|
+
console.warn('❌ addLayer failed: currentCase not initialized');
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const uuid = layer.uuid || uuidv4();
|
|
202
|
+
const zIndex = layers.value.length + 1;
|
|
203
|
+
const newLayer = {
|
|
204
|
+
...cloneDeep(DEFAULT_LAYER), // 使用cloneDeep防止展开运算符的浅拷贝无法处理嵌套对象,导致污染初始值
|
|
205
|
+
...cloneDeep(layer),
|
|
206
|
+
uuid,
|
|
207
|
+
zIndex,
|
|
208
|
+
rawData: {
|
|
209
|
+
id: uuid
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
// 直接 push 到响应式数组
|
|
213
|
+
currentCase.value.layers.push(newLayer);
|
|
214
|
+
// 添加后重绘
|
|
215
|
+
if (!appContainer) {
|
|
216
|
+
console.warn('❌ addLayer failed: appContainer not initialized');
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
appContainer.addModel(newLayer);
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* 切换选中图层,选中对应的 UI
|
|
223
|
+
*/
|
|
224
|
+
const selectLayer = (uuid) => {
|
|
225
|
+
if (editorManager) {
|
|
226
|
+
const isCurrentLayer = currentLayer.value?.uuid === uuid;
|
|
227
|
+
editorManager.selectEquipment(isCurrentLayer ? undefined : `#${uuid}`);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
// ==================== 监听器 ====================
|
|
231
|
+
// 监听场景配置变化
|
|
232
|
+
watch(scene, () => {
|
|
233
|
+
if (appContainer) {
|
|
234
|
+
updateScene();
|
|
235
|
+
}
|
|
236
|
+
}, { deep: true });
|
|
237
|
+
// 监听当前选中图层的变化,更新图形 UI
|
|
238
|
+
watch(currentLayer, (layer) => {
|
|
239
|
+
if (layer) {
|
|
240
|
+
updateLayer(layer);
|
|
241
|
+
rerenderLayer(layer);
|
|
242
|
+
}
|
|
243
|
+
}, { deep: true });
|
|
244
|
+
return {
|
|
245
|
+
// Getters
|
|
246
|
+
currentCase,
|
|
247
|
+
scene,
|
|
248
|
+
layers,
|
|
249
|
+
currentLayer,
|
|
250
|
+
// Actions
|
|
251
|
+
initContainer,
|
|
252
|
+
resizeContainer,
|
|
253
|
+
destroyContainer,
|
|
254
|
+
initEditor,
|
|
255
|
+
// 场景
|
|
256
|
+
updateScene,
|
|
257
|
+
// 当前图层
|
|
258
|
+
addLayer,
|
|
259
|
+
selectLayer,
|
|
260
|
+
updateLayer,
|
|
261
|
+
renderLayers
|
|
262
|
+
};
|
|
263
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EnumInteractiveUi } from './enums';
|
|
1
|
+
import { type EnumInteractiveUi } from './enums';
|
|
2
2
|
/**
|
|
3
3
|
* 原始业务数据
|
|
4
4
|
*/
|
|
@@ -11,7 +11,7 @@ export type IRowData = {
|
|
|
11
11
|
export interface IInteractiveState {
|
|
12
12
|
hittable?: boolean;
|
|
13
13
|
hitSelf?: boolean;
|
|
14
|
-
visible?: boolean;
|
|
14
|
+
visible?: boolean | 0;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* 事件状态
|
|
@@ -35,4 +35,6 @@ export interface IBaseConfig {
|
|
|
35
35
|
height: number;
|
|
36
36
|
x?: number;
|
|
37
37
|
y?: number;
|
|
38
|
+
zIndex?: number;
|
|
39
|
+
rotation?: number;
|
|
38
40
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {} from './enums';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { IRowData, IBaseConfig, IInteractiveState } from '../base.types';
|
|
1
|
+
import type { IRowData, IBaseConfig, IInteractiveState } from '../base.types';
|
|
2
2
|
import { EnumResourceType, EnumComponent } from '../enums';
|
|
3
|
+
export type IOriginAround = 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
3
4
|
/**
|
|
4
5
|
* 工位
|
|
5
6
|
*/
|
|
@@ -11,6 +12,9 @@ export interface IStationSlotConfig extends IBaseConfig, IInteractiveState {
|
|
|
11
12
|
rotation?: number;
|
|
12
13
|
parentRotation?: number;
|
|
13
14
|
disabled?: boolean;
|
|
15
|
+
origin?: IOriginAround;
|
|
16
|
+
around?: IOriginAround;
|
|
17
|
+
showContainer?: boolean;
|
|
14
18
|
}
|
|
15
19
|
/**
|
|
16
20
|
* 布局选项
|
|
@@ -26,8 +30,11 @@ export interface IFlowConfig {
|
|
|
26
30
|
*/
|
|
27
31
|
export interface IStationSlotGroupConfig extends IBaseConfig {
|
|
28
32
|
parentRotation?: number;
|
|
33
|
+
origin?: IOriginAround;
|
|
34
|
+
around?: IOriginAround;
|
|
29
35
|
stationSlots: IStationSlotConfig[];
|
|
30
36
|
flowOptions: IFlowConfig;
|
|
37
|
+
hittable?: boolean;
|
|
31
38
|
}
|
|
32
39
|
/**
|
|
33
40
|
* 资源
|
|
@@ -43,10 +50,11 @@ export interface IResourceConfig extends IBaseConfig, IInteractiveState {
|
|
|
43
50
|
* 状态灯
|
|
44
51
|
*/
|
|
45
52
|
export interface ILightConfig extends IBaseConfig {
|
|
46
|
-
|
|
53
|
+
color?: string;
|
|
47
54
|
strokeColor?: string;
|
|
48
55
|
strokeWidth?: number;
|
|
49
|
-
|
|
56
|
+
cornerRadius?: number | number[];
|
|
57
|
+
showShadow?: boolean;
|
|
50
58
|
}
|
|
51
59
|
/**
|
|
52
60
|
* 进度条
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { EnumResourceType, EnumComponent } from '../enums';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { EnumResourceType } from '../enums';
|