@jnrs/lingshu-smart 2.2.19 → 2.2.21

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.
Files changed (2) hide show
  1. package/AGENTIC.md +1047 -0
  2. package/package.json +3 -2
package/AGENTIC.md ADDED
@@ -0,0 +1,1047 @@
1
+ # @jnrs/lingshu-smart API 文档
2
+
3
+ ## ✨ 介绍
4
+
5
+ 巨能前端 2D 数字孪生库,灵枢智造。提供 2D 数字孪生编辑器和运行看板功能,基于 LeaferJS 引擎构建。
6
+
7
+ ## 📦 模块总览
8
+
9
+ | 模块路径 | 说明 |
10
+ |---------|------|
11
+ | `@jnrs/lingshu-smart` | 主模块,包含类型定义和工具函数 |
12
+ | `@jnrs/lingshu-smart/components` | Vue 组件库(编辑器、预览器) |
13
+ | `@jnrs/lingshu-smart/stores` | Pinia 状态管理 |
14
+ | `@jnrs/lingshu-smart/composables` | Vue 组合式 API |
15
+ | `@jnrs/lingshu-smart/controller` | 控制器类 |
16
+ | `@jnrs/lingshu-smart/types` | TypeScript 类型定义 |
17
+ | `@jnrs/lingshu-smart/utils` | 工具函数 |
18
+ | `@jnrs/lingshu-smart/constants` | 常量配置 |
19
+ | `@jnrs/lingshu-smart/ui` | UI 模型和工厂 |
20
+ | `@jnrs/lingshu-smart/locales` | 国际化配置 |
21
+
22
+ ---
23
+
24
+ ## 📋 API 详情
25
+
26
+ ### @jnrs/lingshu-smart 主模块
27
+
28
+ #### 类型导出
29
+
30
+ 从主模块导出的所有类型:
31
+
32
+ ##### 枚举 (Enums)
33
+
34
+ ###### EnumStepType
35
+
36
+ 步骤操作类型
37
+
38
+ ```typescript
39
+ enum EnumStepType {
40
+ UNDO = 'Undo', // 撤销
41
+ REDO = 'Redo' // 重做
42
+ }
43
+ ```
44
+
45
+ ###### EnumTag
46
+
47
+ 设备标签枚举
48
+
49
+ ```typescript
50
+ enum EnumTag {
51
+ TRANSPORT = '搬运设备',
52
+ MACHINE = '机床',
53
+ CLEANING = '清洗机',
54
+ STATION = '装载站',
55
+ STORAGE = '库',
56
+ OTHER = '其他'
57
+ }
58
+ ```
59
+
60
+ ###### EnumModel
61
+
62
+ 设备类型枚举
63
+
64
+ ```typescript
65
+ enum EnumModel {
66
+ SINGLE_JOINT_ROBOT = 'SingleJointRobot', // 单关节机器人
67
+ DOUBLE_JOINT_ROBOT = 'DoubleJointRobot', // 双关节机器人
68
+ RGV = 'Rgv', // RGV
69
+ MACHINE_TOOL = 'MachineTool', // 机床
70
+ MARKING_MACHINE = 'MarkingMachine', // 打标机
71
+ CLEANING_MACHINE = 'CleaningMachine', // 清洗机
72
+ LOADING_STATION = 'LoadingStation', // 上料站
73
+ PALLET_STORAGE = 'PalletStorage', // 托盘库
74
+ TOOL_STORAGE = 'ToolStorage', // 刀具库
75
+ BUFFER_DOCK = 'BufferDock', // 缓冲站
76
+ GROUND_RAIL = 'GroundRail', // 地轨
77
+ FOLLOWING_TUGGER = 'FollowingTugger', // 跟随牵引车
78
+ RAIL = 'Rail', // 轨道
79
+ RESOURCE_STORE = 'ResourceStore' // 资源库
80
+ }
81
+ ```
82
+
83
+ ###### EnumComponent
84
+
85
+ 组件类型枚举
86
+
87
+ ```typescript
88
+ enum EnumComponent {
89
+ STATION_SLOT = 'StationSlot', // 工位槽
90
+ RESOURCE = 'Resource' // 资源
91
+ }
92
+ ```
93
+
94
+ ###### EnumResourceType
95
+
96
+ 资源类型枚举
97
+
98
+ ```typescript
99
+ enum EnumResourceType {
100
+ PALLET = 'Pallet', // 托盘
101
+ TOOL = 'Tool' // 刀具
102
+ }
103
+ ```
104
+
105
+ ###### EnumInteractiveUi
106
+
107
+ 可交互设备类型
108
+
109
+ ```typescript
110
+ type EnumInteractiveUi = EnumModel | EnumComponent
111
+ ```
112
+
113
+ ##### 核心类型 (Core Types)
114
+
115
+ ###### IScene
116
+
117
+ 场景配置
118
+
119
+ | 属性名 | 类型 | 必填 | 说明 |
120
+ |--------|------|------|------|
121
+ | width | `number` | ✓ | 场景宽度 |
122
+ | height | `number` | ✓ | 场景高度 |
123
+ | runtime_width | `number` | - | 运行时宽度(业务数据) |
124
+ | runtime_height | `number` | - | 运行时高度(业务数据) |
125
+ | zoomType | `'fit' \| number` | ✓ | 缩放类型:'fit' 自适应或具体数值 |
126
+ | fill | `FillConfig` | - | 背景填充配置 |
127
+ | texture | `string` | - | 纹理图片 URL |
128
+
129
+ **FillConfig 类型:**
130
+
131
+ ```typescript
132
+ interface FillConfig {
133
+ type: 'solid' | 'linear' | 'radial' | 'image'
134
+ color: string
135
+ opacity: number
136
+ stops: { offset: number; color: string }[]
137
+ url?: string
138
+ from?: string
139
+ to?: string
140
+ }
141
+ ```
142
+
143
+ ###### ICase
144
+
145
+ 方案(案例)
146
+
147
+ | 属性名 | 类型 | 必填 | 说明 |
148
+ |--------|------|------|------|
149
+ | uuid | `string` | ✓ | 唯一标识 |
150
+ | isActive | `boolean` | ✓ | 是否为当前激活方案 |
151
+ | title | `string` | ✓ | 方案标题 |
152
+ | scene | `IScene` | ✓ | 场景配置 |
153
+ | layers | `ILayer[]` | ✓ | 图层列表 |
154
+
155
+ ###### ILayer
156
+
157
+ 图层基类
158
+
159
+ **说明:** ILayer 是图层的基类,具体实现包括 IModel(设备模型)、IStationSlotConfig(工位槽配置)、IResourceConfig(资源配置)等。
160
+
161
+ ###### InteractiveUi
162
+
163
+ 可交互设备类型
164
+
165
+ ```typescript
166
+ type InteractiveUi = ILayer | IStationSlotConfig | IResourceConfig
167
+ ```
168
+
169
+ ###### IEventHandler
170
+
171
+ 事件处理器
172
+
173
+ | 属性名 | 类型 | 说明 |
174
+ |--------|------|------|
175
+ | onTap | `(layer: ILayer, data: InteractiveUi) => void` | 快速点击事件(左键单击) |
176
+ | onMenuTap | `(layer: ILayer, data: InteractiveUi) => void` | 右键 tap 事件(右键单击) |
177
+ | onDragEnd | `(layer: ILayer, data: InteractiveUi) => void` | 拖动结束事件 |
178
+
179
+ ###### IContainer
180
+
181
+ 容器配置
182
+
183
+ | 属性名 | 类型 | 默认值 | 说明 |
184
+ |--------|------|--------|------|
185
+ | appDomId | `string \| HTMLElement` | — | APP 容器 DOM ID 或元素 |
186
+ | autoStart | `boolean` | `true` | 是否自动启动引擎 |
187
+ | appEditable | `boolean` | `false` | APP 是否可编辑状态 |
188
+ | actions | `IEventHandler` | — | 事件处理配置 |
189
+
190
+ ##### 工具函数 (Utils)
191
+
192
+ ###### numberLoopGenerator
193
+
194
+ 数字生成器
195
+
196
+ **参数:**
197
+
198
+ | 参数名 | 类型 | 默认值 | 说明 |
199
+ |--------|------|--------|------|
200
+ | start | `number` | — | 起始值 |
201
+ | end | `number` | — | 结束值 |
202
+ | shouldLoop | `boolean` | `false` | 是否无限循环 |
203
+
204
+ **返回值:** `Generator<number>` - 数字生成器
205
+
206
+ **使用示例:**
207
+
208
+ ```typescript
209
+ import { numberLoopGenerator } from '@jnrs/lingshu-smart'
210
+
211
+ const gen = numberLoopGenerator(1, 10, false)
212
+ for (const num of gen) {
213
+ console.log(num) // 1, 2, 3, ..., 10
214
+ }
215
+ ```
216
+
217
+ ###### linearIncrease
218
+
219
+ 在 n 秒内把变量从值 x 线性递增到 y
220
+
221
+ **参数:**
222
+
223
+ | 参数名 | 类型 | 默认值 | 说明 |
224
+ |--------|------|--------|------|
225
+ | x | `number` | `0` | 初始值 |
226
+ | y | `number` | `100` | 结束值 |
227
+ | n | `number` | `3` | 递增时长(秒) |
228
+ | rate | `number` | `300` | 帧率(ms) |
229
+ | callback | `(val: number \| string) => void` | — | 回调函数 |
230
+
231
+ **返回值:** `Promise<void>`
232
+
233
+ **使用示例:**
234
+
235
+ ```typescript
236
+ import { linearIncrease } from '@jnrs/lingshu-smart'
237
+
238
+ await linearIncrease(0, 100, 3, 300, (val) => {
239
+ console.log('当前值:', val)
240
+ })
241
+ ```
242
+
243
+ ###### transPercentAndPixel
244
+
245
+ 根据百分比数字转换为像素,或者根据像素转换为百分比
246
+
247
+ **参数:**
248
+
249
+ | 参数名 | 类型 | 默认值 | 说明 |
250
+ |--------|------|--------|------|
251
+ | val | `number` | — | 百分比数字(0~1)或像素数字 |
252
+ | size | `number` | — | 尺寸,用于计算百分比 |
253
+ | precision | `number` | `3` | 保留的小数位数 |
254
+ | getPercent | `boolean` | `false` | 是否返回百分比 |
255
+
256
+ **返回值:** `number` - 转换后的值
257
+
258
+ **使用示例:**
259
+
260
+ ```typescript
261
+ import { transPercentAndPixel } from '@jnrs/lingshu-smart'
262
+
263
+ // 百分比转像素
264
+ const pixel = transPercentAndPixel(0.5, 1920, 0, false) // 960
265
+
266
+ // 像素转百分比
267
+ const percent = transPercentAndPixel(960, 1920, 3, true) // 0.5
268
+ ```
269
+
270
+ ###### transFraction
271
+
272
+ 百分比转换小数
273
+
274
+ **参数:**
275
+
276
+ | 参数名 | 类型 | 默认值 | 说明 |
277
+ |--------|------|--------|------|
278
+ | val | `number` | — | 值 |
279
+ | size | `number` | — | 尺寸 |
280
+
281
+ **返回值:** `number` - 转换后的小数
282
+
283
+ ###### transRuntimeToPixel
284
+
285
+ 运行时数值转换为像素数值
286
+
287
+ **参数:**
288
+
289
+ | 参数名 | 类型 | 默认值 | 说明 |
290
+ |--------|------|--------|------|
291
+ | val | `number` | — | 运行时数值 |
292
+ | precision | `number` | `0` | 精度 |
293
+ | type | `'width' \| 'height'` | `'width'` | 类型 |
294
+
295
+ **返回值:** `number` - 像素数值
296
+
297
+ **注意:** 此函数依赖 `useEditorStore`,仅在编辑器环境中可用。
298
+
299
+ ---
300
+
301
+ ### @jnrs/lingshu-smart/components 模块
302
+
303
+ #### LingshuSmartEditor
304
+
305
+ 编辑器组件,提供 2D 数字孪生方案的可视化编辑功能。
306
+
307
+ **Props:**
308
+
309
+ | 属性名 | 类型 | 默认值 | 说明 |
310
+ |--------|------|--------|------|
311
+ | actions | `EditorActions` | `{}` | 事件处理配置 |
312
+
313
+ **EditorActions 接口:**
314
+
315
+ ```typescript
316
+ interface EditorActions {
317
+ /**
318
+ * 加载案例列表
319
+ * @param id - 可选的案例 ID
320
+ * @returns Promise<ICase[]>
321
+ */
322
+ loadCases?: (id?: string) => Promise<ICase[]>
323
+
324
+ /**
325
+ * 保存方案列表
326
+ * @param cases - 方案列表
327
+ */
328
+ saveCases?: (cases?: ICase[]) => void
329
+
330
+ /**
331
+ * 跳转到预览页面
332
+ * @param currentCase - 当前方案
333
+ */
334
+ handlePreview?: (currentCase?: ICase) => void
335
+
336
+ /**
337
+ * 退出当前页面
338
+ */
339
+ handleExit?: () => void
340
+ }
341
+ ```
342
+
343
+ **使用示例:**
344
+
345
+ ```vue
346
+ <template>
347
+ <LingshuSmartEditor :actions="editorActions" />
348
+ </template>
349
+
350
+ <script setup>
351
+ import { LingshuSmartEditor } from '@jnrs/lingshu-smart/components'
352
+
353
+ const editorActions = {
354
+ async loadCases(id) {
355
+ const res = await fetch(`/api/cases/${id || ''}`)
356
+ return res.json()
357
+ },
358
+ saveCases(cases) {
359
+ fetch('/api/cases', {
360
+ method: 'POST',
361
+ body: JSON.stringify(cases)
362
+ })
363
+ },
364
+ handlePreview(currentCase) {
365
+ window.open(`/preview/${currentCase.uuid}`)
366
+ },
367
+ handleExit() {
368
+ window.history.back()
369
+ }
370
+ }
371
+ </script>
372
+ ```
373
+
374
+ **功能特性:**
375
+
376
+ - 左侧菜单卡片:设备库、图层管理
377
+ - 中间画布:可视化编辑区域
378
+ - 右侧选项卡片:属性配置面板
379
+ - 顶部控制栏:方案标题编辑、方案管理、步骤记录(撤销/重做)
380
+ - 支持拖拽、缩放、旋转等操作
381
+ - 自动保存和版本管理
382
+
383
+ ---
384
+
385
+ #### LingshuSmartPreview
386
+
387
+ 预览组件,用于运行和展示 2D 数字孪生方案。
388
+
389
+ **Props:**
390
+
391
+ | 属性名 | 类型 | 默认值 | 说明 |
392
+ |--------|------|--------|------|
393
+ | actions | `PreviewActions` | `{}` | 事件处理配置 |
394
+ | caseUuid | `string` | — | 案例 UUID |
395
+
396
+ **PreviewActions 接口:**
397
+
398
+ ```typescript
399
+ interface PreviewActions {
400
+ /**
401
+ * 加载案例列表
402
+ * @param id - 可选的案例 ID
403
+ * @returns Promise<ICase[]>
404
+ */
405
+ loadCases?: (id?: string) => Promise<ICase[]>
406
+
407
+ /**
408
+ * 点击事件
409
+ * @param layer - 图层
410
+ * @param data - 设备信息
411
+ */
412
+ onTap?: (layer: ILayer, data: InteractiveUi) => void
413
+
414
+ /**
415
+ * 右键点击事件
416
+ * @param layer - 图层
417
+ * @param data - 设备信息
418
+ */
419
+ onMenuTap?: (layer: ILayer, data: InteractiveUi) => void
420
+
421
+ /**
422
+ * 拖拽结束事件
423
+ * @param layer - 图层
424
+ * @param data - 设备信息
425
+ */
426
+ onDragEnd?: (layer: ILayer, data: InteractiveUi) => void
427
+ }
428
+ ```
429
+
430
+ **使用示例:**
431
+
432
+ ```vue
433
+ <template>
434
+ <LingshuSmartPreview
435
+ :case-uuid="caseUuid"
436
+ :actions="previewActions"
437
+ />
438
+ </template>
439
+
440
+ <script setup>
441
+ import { ref } from 'vue'
442
+ import { LingshuSmartPreview } from '@jnrs/lingshu-smart/components'
443
+
444
+ const caseUuid = ref('abc-123-def')
445
+
446
+ const previewActions = {
447
+ async loadCases() {
448
+ const res = await fetch('/api/cases')
449
+ return res.json()
450
+ },
451
+ onTap(layer, data) {
452
+ console.log('点击设备:', data)
453
+ },
454
+ onMenuTap(layer, data) {
455
+ console.log('右键点击:', data)
456
+ }
457
+ }
458
+ </script>
459
+ ```
460
+
461
+ **功能特性:**
462
+
463
+ - 只读模式,不支持编辑
464
+ - 支持设备点击、右键菜单交互
465
+ - 自适应窗口大小
466
+ - 自动加载指定案例
467
+ - 支持自定义事件回调
468
+
469
+ ---
470
+
471
+ ### @jnrs/lingshu-smart/stores 模块
472
+
473
+ #### useDataStore
474
+
475
+ 数据仓库,管理设备菜单、方案列表等全局数据。
476
+
477
+ **返回值:**
478
+
479
+ | 属性/方法 | 类型 | 说明 |
480
+ |-----------|------|------|
481
+ | equipmentsMenu | `Ref<IEquipmentsMenu[]>` | 设备菜单(预设) |
482
+ | cases | `Ref<ICase[] \| undefined>` | 方案列表 |
483
+ | casesLoading | `Ref<boolean>` | 方案加载状态 |
484
+ | updateCases | `(data?: ICase[]) => void` | 更新方案列表 |
485
+ | selectCase | `(uuid: string) => void` | 切换当前方案 |
486
+ | addCase | `(data?: ICase) => void` | 添加方案 |
487
+ | removeCase | `(uuid: string) => void` | 删除方案 |
488
+ | updateCase | `(uuid: string, data: Partial<ICase>) => void` | 更新方案 |
489
+
490
+ **使用示例:**
491
+
492
+ ```typescript
493
+ import { useDataStore } from '@jnrs/lingshu-smart/stores'
494
+
495
+ const dataStore = useDataStore()
496
+
497
+ // 更新方案列表
498
+ dataStore.updateCases([
499
+ {
500
+ uuid: 'case-1',
501
+ title: '方案1',
502
+ isActive: true,
503
+ scene: { /* ... */ },
504
+ layers: []
505
+ }
506
+ ])
507
+
508
+ // 切换方案
509
+ dataStore.selectCase('case-1')
510
+
511
+ // 添加新方案
512
+ dataStore.addCase({
513
+ uuid: '',
514
+ title: '新方案',
515
+ isActive: false,
516
+ scene: { /* ... */ },
517
+ layers: []
518
+ })
519
+
520
+ // 访问方案列表
521
+ console.log(dataStore.cases.value)
522
+ ```
523
+
524
+ ---
525
+
526
+ #### useEditorStore
527
+
528
+ 编辑器仓库,管理编辑器实例、当前方案、场景、图层等状态。
529
+
530
+ **返回值:**
531
+
532
+ | 属性/方法 | 类型 | 说明 |
533
+ |-----------|------|------|
534
+ | currentCase | `ComputedRef<ICase \| null>` | 当前选择的方案 |
535
+ | scene | `ComputedRef<IScene \| null>` | 当前方案场景 |
536
+ | layers | `ComputedRef<ILayer[]>` | 当前方案图层列表 |
537
+ | currentLayer | `ComputedRef<ILayer \| null>` | 当前选择的图层 |
538
+ | initContainer | `(options: IContainer) => void` | 初始化容器(引擎实例) |
539
+ | updateScene | `() => void` | 修改场景(防抖) |
540
+ | addLayer | `(layer: ILayer) => void` | 添加图层 |
541
+ | removeLayer | `(uuid: string) => void` | 删除图层 |
542
+ | updateLayer | `(uuid: string, data: Partial<ILayer>) => void` | 更新图层 |
543
+ | selectLayer | `(uuid: string) => void` | 选择图层 |
544
+ | resizeContainer | `() => void` | 重置容器大小 |
545
+ | destroyContainer | `() => void` | 销毁容器 |
546
+ | operating | `Ref<ILayerOperating \| null>` | 当前操作状态 |
547
+
548
+ **使用示例:**
549
+
550
+ ```typescript
551
+ import { useEditorStore } from '@jnrs/lingshu-smart/stores'
552
+
553
+ const editorStore = useEditorStore()
554
+
555
+ // 初始化容器
556
+ editorStore.initContainer({
557
+ appDomId: 'editor-app',
558
+ appEditable: true,
559
+ actions: {
560
+ onTap: (layer, data) => {
561
+ console.log('点击图层', layer)
562
+ }
563
+ }
564
+ })
565
+
566
+ // 添加图层
567
+ editorStore.addLayer({
568
+ uuid: 'layer-1',
569
+ equipmentName: '机器人',
570
+ x: 100,
571
+ y: 100,
572
+ width: 200,
573
+ height: 200,
574
+ // ... 其他属性
575
+ })
576
+
577
+ // 选择图层
578
+ editorStore.selectLayer('layer-1')
579
+
580
+ // 访问当前方案
581
+ console.log(editorStore.currentCase.value)
582
+ console.log(editorStore.scene.value)
583
+ ```
584
+
585
+ ---
586
+
587
+ #### useAppStore
588
+
589
+ 应用仓库,用于预览模式的容器管理。
590
+
591
+ **返回值:**
592
+
593
+ | 属性/方法 | 类型 | 说明 |
594
+ |-----------|------|------|
595
+ | currentCase | `ComputedRef<ICase \| null>` | 当前方案 |
596
+ | initContainer | `(options: IContainer, caseUuid: string) => void` | 初始化容器并加载指定案例 |
597
+ | resizeContainer | `() => void` | 重置容器大小 |
598
+ | destroyContainer | `() => void` | 销毁容器 |
599
+ | operating | `Ref<ILayerOperating \| null>` | 当前操作状态 |
600
+
601
+ **使用示例:**
602
+
603
+ ```typescript
604
+ import { useAppStore } from '@jnrs/lingshu-smart/stores'
605
+
606
+ const appStore = useAppStore()
607
+
608
+ // 初始化预览容器
609
+ appStore.initContainer({
610
+ appDomId: 'preview-app',
611
+ appEditable: false,
612
+ actions: {
613
+ onTap: (layer, data) => {
614
+ console.log('点击设备', data)
615
+ }
616
+ }
617
+ }, 'case-uuid-123')
618
+ ```
619
+
620
+ ---
621
+
622
+ ### @jnrs/lingshu-smart/composables 模块
623
+
624
+ #### useStepRecord
625
+
626
+ 编辑操作记录 Hook,提供撤销/重做功能。
627
+
628
+ **返回值:**
629
+
630
+ | 返回值 | 类型 | 说明 |
631
+ |--------|------|------|
632
+ | operationRecordStatus | `ComputedRef<{ canUndo: boolean; canRedo: boolean; totalSteps: number; currentIndex: number }>` | 操作记录状态 |
633
+ | recordOperation | `(caseData: ICase[], hash: string) => void` | 记录操作(防抖 300ms) |
634
+ | undo | `() => void` | 撤销操作 |
635
+ | redo | `() => void` | 重做操作 |
636
+ | jumpToStep | `(index: number) => void` | 跳转到任意历史点 |
637
+ | clearRecord | `() => void` | 清空记录 |
638
+
639
+ **使用示例:**
640
+
641
+ ```typescript
642
+ import { useStepRecord } from '@jnrs/lingshu-smart/composables'
643
+
644
+ const {
645
+ operationRecordStatus,
646
+ recordOperation,
647
+ undo,
648
+ redo,
649
+ jumpToStep
650
+ } = useStepRecord()
651
+
652
+ // 检查是否可以撤销/重做
653
+ console.log(operationRecordStatus.value.canUndo)
654
+ console.log(operationRecordStatus.value.canRedo)
655
+
656
+ // 记录操作(通常在数据变更后调用)
657
+ import objectHash from 'object-hash'
658
+ const hash = objectHash(cases.value)
659
+ recordOperation(cases.value, hash)
660
+
661
+ // 撤销
662
+ undo()
663
+
664
+ // 重做
665
+ redo()
666
+
667
+ // 跳转到第 5 步
668
+ jumpToStep(5)
669
+ ```
670
+
671
+ **特性:**
672
+
673
+ - 最多保存 10 条操作记录
674
+ - 防抖处理(300ms),避免频繁记录
675
+ - 支持跳转到任意历史点
676
+ - 自动检测数据变化,避免重复记录
677
+ - TODO: 未来可迁移至 IndexedDB 以支持持久化
678
+
679
+ ---
680
+
681
+ ### @jnrs/lingshu-smart/controller 模块
682
+
683
+ #### AppController
684
+
685
+ 主画布、模型容器控制器,基于 LeaferJS 引擎。
686
+
687
+ **构造函数:**
688
+
689
+ ```typescript
690
+ constructor(options: IContainer = {})
691
+ ```
692
+
693
+ **参数:**
694
+
695
+ | 参数名 | 类型 | 默认值 | 说明 |
696
+ |--------|------|--------|------|
697
+ | options | `IContainer` | `{}` | 容器配置 |
698
+
699
+ **方法:**
700
+
701
+ ###### start
702
+
703
+ 启动/重启引擎
704
+
705
+ **返回值:** `void`
706
+
707
+ ###### destroy
708
+
709
+ 销毁引擎(异步销毁,不会立即执行)
710
+
711
+ **返回值:** `void`
712
+
713
+ ###### setZoom
714
+
715
+ 控制视图的缩放
716
+
717
+ **参数:**
718
+
719
+ | 参数名 | 类型 | 默认值 | 说明 |
720
+ |--------|------|--------|------|
721
+ | zoomType | `'fit' \| number` | `'fit'` | 缩放类型 |
722
+ | duration | `number` | `0.5` | 动画时长(秒) |
723
+
724
+ **返回值:** `void`
725
+
726
+ ###### setTree
727
+
728
+ 修改 tree 配置
729
+
730
+ **参数:**
731
+
732
+ | 参数名 | 类型 | 说明 |
733
+ |--------|------|------|
734
+ | data | `IScene` | 场景配置,不传则重置为默认配置 |
735
+
736
+ **返回值:** `void`
737
+
738
+ ###### getTreeElements
739
+
740
+ tree 层查找元素
741
+
742
+ **返回值:** `Array` - 元素数组
743
+
744
+ ###### addModel
745
+
746
+ 添加模型到画布
747
+
748
+ **参数:**
749
+
750
+ | 参数名 | 类型 | 说明 |
751
+ |--------|------|------|
752
+ | layer | `ILayer` | 图层数据 |
753
+
754
+ **返回值:** `ModelAbs` - 模型实例
755
+
756
+ ###### removeModel
757
+
758
+ 从画布移除模型
759
+
760
+ **参数:**
761
+
762
+ | 参数名 | 类型 | 说明 |
763
+ |--------|------|------|
764
+ | uuid | `string` | 图层 UUID |
765
+
766
+ **返回值:** `void`
767
+
768
+ ###### updateModel
769
+
770
+ 更新模型属性
771
+
772
+ **参数:**
773
+
774
+ | 参数名 | 类型 | 说明 |
775
+ |--------|------|------|
776
+ | uuid | `string` | 图层 UUID |
777
+ | data | `Partial<ILayer>` | 更新的属性 |
778
+
779
+ **返回值:** `void`
780
+
781
+ ###### clearAll
782
+
783
+ 清空所有模型
784
+
785
+ **返回值:** `void`
786
+
787
+ **使用示例:**
788
+
789
+ ```typescript
790
+ import { AppController } from '@jnrs/lingshu-smart/controller'
791
+
792
+ const controller = new AppController({
793
+ appDomId: 'app-container',
794
+ appEditable: true,
795
+ autoStart: true,
796
+ actions: {
797
+ onTap: (layer, data) => {
798
+ console.log('点击', data)
799
+ }
800
+ }
801
+ })
802
+
803
+ // 启动引擎
804
+ controller.start()
805
+
806
+ // 设置场景
807
+ controller.setTree({
808
+ width: 1920,
809
+ height: 1080,
810
+ zoomType: 'fit',
811
+ fill: { type: 'solid', color: '#fff', opacity: 1, stops: [] }
812
+ })
813
+
814
+ // 添加模型
815
+ const model = controller.addModel(layerData)
816
+
817
+ // 更新模型
818
+ controller.updateModel('layer-uuid', { x: 100, y: 100 })
819
+
820
+ // 移除模型
821
+ controller.removeModel('layer-uuid')
822
+
823
+ // 销毁
824
+ controller.destroy()
825
+ ```
826
+
827
+ ---
828
+
829
+ #### EditorController
830
+
831
+ 编辑器控制器,提供编辑相关的功能。
832
+
833
+ **说明:** EditorController 继承自 AppController,额外提供编辑器特有的功能,如选中框、辅助线、网格等。
834
+
835
+ **主要功能:**
836
+
837
+ - 图层选中高亮
838
+ - 拖拽移动
839
+ - 旋转、缩放
840
+ - 对齐辅助线
841
+ - 网格显示
842
+ - 层级管理(zIndex)
843
+
844
+ ---
845
+
846
+ ### @jnrs/lingshu-smart/types 模块
847
+
848
+ 详细的类型定义请参考上述"核心类型"部分,包括:
849
+
850
+ - **场景相关:** IScene, ICase
851
+ - **图层相关:** ILayer, IModel, IStationSlotConfig, IResourceConfig
852
+ - **交互相关:** IEventHandler, IContainer, InteractiveUi
853
+ - **枚举类型:** EnumStepType, EnumTag, EnumModel, EnumComponent, EnumResourceType
854
+
855
+ 所有类型均从 `@jnrs/lingshu-smart` 主模块导出。
856
+
857
+ ---
858
+
859
+ ### @jnrs/lingshu-smart/constants 模块
860
+
861
+ #### CASE_INIT
862
+
863
+ 新方案默认值
864
+
865
+ ```typescript
866
+ const CASE_INIT: ICase = {
867
+ uuid: '',
868
+ title: '',
869
+ isActive: false,
870
+ layers: [],
871
+ scene: {
872
+ width: 1920,
873
+ height: 1080,
874
+ zoomType: 'fit',
875
+ fill: {
876
+ type: 'solid',
877
+ color: '#000',
878
+ opacity: 1,
879
+ stops: []
880
+ },
881
+ texture: ''
882
+ }
883
+ }
884
+ ```
885
+
886
+ #### DEFAULT_LAYER
887
+
888
+ 新图层默认值
889
+
890
+ ```typescript
891
+ const DEFAULT_LAYER: IModel = {
892
+ rawData: { id: '' },
893
+ uuid: '',
894
+ equipmentName: '',
895
+ width: 0,
896
+ height: 0,
897
+ x: 0,
898
+ y: 0,
899
+ percentX: 0,
900
+ percentY: 0,
901
+ rotation: 0,
902
+ scale: 1,
903
+ zIndex: 1,
904
+ visible: true,
905
+ clickable: true,
906
+ menuClickable: true,
907
+ draggable: false,
908
+ editable: true,
909
+ selected: false
910
+ }
911
+ ```
912
+
913
+ ---
914
+
915
+ ## 🔍 完整使用示例
916
+
917
+ ### 编辑器模式
918
+
919
+ ```vue
920
+ <template>
921
+ <LingshuSmartEditor :actions="editorActions" />
922
+ </template>
923
+
924
+ <script setup>
925
+ import { LingshuSmartEditor } from '@jnrs/lingshu-smart/components'
926
+ import { useDataStore } from '@jnrs/lingshu-smart/stores'
927
+
928
+ const dataStore = useDataStore()
929
+
930
+ const editorActions = {
931
+ async loadCases(id) {
932
+ const res = await fetch(`/api/cases/${id || ''}`)
933
+ const data = await res.json()
934
+ dataStore.updateCases(data)
935
+ return data
936
+ },
937
+ saveCases(cases) {
938
+ fetch('/api/cases', {
939
+ method: 'POST',
940
+ headers: { 'Content-Type': 'application/json' },
941
+ body: JSON.stringify(cases)
942
+ })
943
+ },
944
+ handlePreview(currentCase) {
945
+ window.open(`/preview/${currentCase?.uuid}`)
946
+ },
947
+ handleExit() {
948
+ if (confirm('确定要退出吗?')) {
949
+ window.history.back()
950
+ }
951
+ }
952
+ }
953
+ </script>
954
+ ```
955
+
956
+ ### 预览模式
957
+
958
+ ```vue
959
+ <template>
960
+ <LingshuSmartPreview
961
+ :case-uuid="caseUuid"
962
+ :actions="previewActions"
963
+ />
964
+ </template>
965
+
966
+ <script setup>
967
+ import { ref } from 'vue'
968
+ import { LingshuSmartPreview } from '@jnrs/lingshu-smart/components'
969
+
970
+ const caseUuid = ref('abc-123-def')
971
+
972
+ const previewActions = {
973
+ async loadCases() {
974
+ const res = await fetch('/api/cases')
975
+ return res.json()
976
+ },
977
+ onTap(layer, data) {
978
+ console.log('点击设备:', data)
979
+ // 显示设备详情
980
+ },
981
+ onMenuTap(layer, data) {
982
+ console.log('右键菜单:', data)
983
+ // 显示右键菜单
984
+ }
985
+ }
986
+ </script>
987
+ ```
988
+
989
+ ### 使用 Store
990
+
991
+ ```typescript
992
+ import { useDataStore, useEditorStore, useStepRecord } from '@jnrs/lingshu-smart/stores'
993
+
994
+ // 数据管理
995
+ const dataStore = useDataStore()
996
+ dataStore.updateCases(cases)
997
+ dataStore.selectCase('case-uuid')
998
+
999
+ // 编辑器管理
1000
+ const editorStore = useEditorStore()
1001
+ editorStore.initContainer({
1002
+ appDomId: 'editor',
1003
+ appEditable: true
1004
+ })
1005
+ editorStore.addLayer(layerData)
1006
+ editorStore.selectLayer('layer-uuid')
1007
+
1008
+ // 撤销/重做
1009
+ const stepRecord = useStepRecord()
1010
+ stepRecord.undo()
1011
+ stepRecord.redo()
1012
+ ```
1013
+
1014
+ ---
1015
+
1016
+ ## 📝 注意事项
1017
+
1018
+ 1. **引擎初始化**:使用前必须调用 `initContainer` 初始化 LeaferJS 引擎
1019
+ 2. **方案管理**:方案数据通过 `useDataStore` 统一管理,确保数据一致性
1020
+ 3. **编辑器 vs 预览器**:
1021
+ - 编辑器模式(`appEditable: true`)支持拖拽、旋转、缩放等编辑操作
1022
+ - 预览模式(`appEditable: false`)为只读模式,仅支持交互事件
1023
+ 4. **性能优化**:
1024
+ - `updateScene` 和 `recordOperation` 均使用防抖处理
1025
+ - 大量图层时建议启用虚拟化渲染
1026
+ 5. **类型安全**:所有 API 均提供完整的 TypeScript 类型定义
1027
+ 6. **事件处理**:通过 `actions` 配置自定义事件回调,实现业务逻辑解耦
1028
+ 7. **资源管理**:组件卸载时记得调用 `destroyContainer` 清理引擎资源
1029
+ 8. **版本兼容**:基于 LeaferJS 构建,请确保版本兼容性
1030
+
1031
+ ---
1032
+
1033
+ ## 🛠 技术栈
1034
+
1035
+ - **Vue 3** - 前端框架
1036
+ - **TypeScript** - 类型系统
1037
+ - **Pinia** - 状态管理
1038
+ - **LeaferJS** - 2D 图形引擎
1039
+ - **Element Plus** - UI 组件库
1040
+ - **object-hash** - 对象哈希计算(用于撤销/重做)
1041
+ - **lodash-es** - 工具函数库
1042
+
1043
+ ---
1044
+
1045
+ ## 📄 License
1046
+
1047
+ UNLICENSED
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jnrs/lingshu-smart",
3
- "version": "2.2.19",
3
+ "version": "2.2.21",
4
4
  "description": "LingShu Smart 2D Digital Twin System.",
5
5
  "keywords": [
6
6
  "jnrs",
@@ -21,6 +21,7 @@
21
21
  "files": [
22
22
  "dist",
23
23
  "README.md",
24
+ "AGENTIC.md",
24
25
  "LICENSE"
25
26
  ],
26
27
  "exports": {
@@ -45,7 +46,7 @@
45
46
  "pinia-plugin-persistedstate": "^4.7.1",
46
47
  "vue": "^3.5.22",
47
48
  "vue-i18n": "^9.14.5",
48
- "@jnrs/shared": "1.1.24"
49
+ "@jnrs/shared": "1.1.25"
49
50
  },
50
51
  "devDependencies": {
51
52
  "@types/lodash-es": "^4.17.12",