@mx-sose-front/mx-sose-graph 1.1.1 → 1.1.2

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.
@@ -22,20 +22,27 @@
22
22
  :actionButtonShapeDataId="actionButtonShapeId" @edit-name="handleEditName"
23
23
  @update-shape="handleUpdateConnectShape" @diagramDoubleClick="handleDiagramDoubleClick"
24
24
  @connect-end="handleConnectEnd" @action-button-click="handleActionButtonClick"
25
+ @object-flow-connect-end="handleObjectFlowConnectEnd"
25
26
  @model-type-property-id-button-click="handleModelTypePropertyIdButtonClick" :lines="props.lines"
26
27
  :packages="props.packages" :diagram="props.diagram" :tagged-value-labels="props.taggedValueLabels"
27
28
  @action-button-add="handleActionButtonAdd" />
28
29
  </div>
29
-
30
+
31
+ <!-- 所在图表 -->
32
+ <DiagramListTooltip :visible="tooltipVisible" :x="tooltipX" :y="tooltipY" :current-diagram-id="currentDiagramId"
33
+ @close="tooltipVisible = false" :diagram-location-data="chartLocationData || []" />
34
+
30
35
  <!-- 缩放条 -->
31
- <div class="zoom-bar">
32
- <button @click="handleZoomOut" class="zoom-button zoom-out">-</button>
33
- <div class="zoom-slider">
34
- <input type="range" min="0.1" max="3" step="0.1" v-model="zoomValue" @input="handleZoomChange" />
35
- </div>
36
- <button @click="handleZoomIn" class="zoom-button zoom-in">+</button>
37
- <div class="zoom-level">{{ Math.round(currentScale * 100) }}%</div>
38
- </div>
36
+ <ZoomSlider
37
+ v-model="zoomValue"
38
+ :min="0.1"
39
+ :max="3"
40
+ :step="0.1"
41
+ @zoom-in="handleZoomIn"
42
+ @zoom-out="handleZoomOut"
43
+ @scale-change="handleScaleChange"
44
+ v-if="graphStore.canOperate"
45
+ />
39
46
  </div>
40
47
  </template>
41
48
 
@@ -43,7 +50,7 @@
43
50
  import { ref, onMounted, computed, watch, nextTick, onUnmounted } from 'vue'
44
51
  import normalizeWheel from 'normalize-wheel-es'
45
52
  import InteractionLayer from '../components/InteractionLayer.vue'
46
- import type { Shape } from '../types'
53
+ import type { locationChart, Shape } from '../types'
47
54
  import { useGraphStore } from '../store/graphStore'
48
55
  // 导入组件
49
56
  import StrategicTaxonomyDiagram from '../components/Diagram/StrategicTaxonomyDiagram.vue'
@@ -63,6 +70,9 @@ import { getShapeComponent, getShapeStyle } from "../render/shape-renderer";
63
70
  import { ShapeConfig } from '../utils/diagram'
64
71
  import { setCompartmentZones, buildZones, setTaggedValueLabelsCache, setPackageTypesCache } from '../utils/compartment'
65
72
  import { eventBus } from "../store";
73
+ import { guardOperate } from "../utils/license-guard"
74
+ import DiagramListTooltip from '../components/DiagramListTooltip/DiagramListTooltip.vue';
75
+ import ZoomSlider from '../components/ZoomSlider/ZoomSlider.vue'
66
76
 
67
77
  registerShapes({
68
78
  StrategicTaxonomyDiagram,
@@ -79,12 +89,19 @@ registerShapes({
79
89
  Port
80
90
  })
81
91
  const interactionLayerRef = ref<InstanceType<typeof InteractionLayer> | null>(null)
92
+
93
+ // 所在图表弹窗相关变量
94
+ const tooltipVisible = ref(false)
95
+ const tooltipX = ref(0)
96
+ const tooltipY = ref(0)
97
+ const currentDiagramId = ref<string>('')
98
+
82
99
  const props = defineProps<{
83
100
  addShapeData: Shape,
84
101
  connectShapeData: Shape,
85
- lines: String[],
102
+ lines: string[],
86
103
  packages: string[],
87
- diagram: String[],
104
+ diagram: string[],
88
105
  taggedValueLabels: string[],
89
106
  actionButtonShapeId?: string,
90
107
  classMetaTypes: string[],
@@ -92,12 +109,15 @@ const props = defineProps<{
92
109
  pins: string[],
93
110
  referentialAttributeModel: string[],
94
111
  ports: string[],
112
+ canOperate: boolean
113
+ chartLocationData?: locationChart[] | null,
95
114
  }>()
96
115
 
97
116
  const emit = defineEmits<{
98
117
  (e: 'shapes-property', value: { selectedShape: Shape, showPropertyPanel: boolean }): void
99
- (e: 'shapes-edit-name', value: { shape: Shape, newName: string }): void
118
+ (e: 'shapes-edit-name', value: { shape: Shape, newName: string, oldName: string }): void
100
119
  (e: 'connect-end', value: { sourceId: string, targetId: string, sourcePoint: { x: number, y: number }, targetPoint: { x: number, y: number }, waypoints: Array<{ x: number, y: number }> }): void
120
+ (e: 'object-flow-connect-end', value: { connectionData: { sourceId: string; targetId: string; sourcePoint: { x: number; y: number }; targetPoint: { x: number; y: number }; waypoints: Array<{ x: number; y: number }> }, outputPinBounds: { x: number; y: number; width: number; height: number }, inputPinBounds: { x: number; y: number; width: number; height: number } }): void
101
121
  (e: 'action-button-click', value: string, shape: Shape): void
102
122
  (e: 'diagramDoubleClick', data: any): void
103
123
  (e: 'model-type-property-id-button-click', value: string, shape: Shape): void
@@ -120,13 +140,14 @@ watch(currentScale, (newScale) => {
120
140
  })
121
141
 
122
142
  // 处理缩放滑块变化
123
- const handleZoomChange = () => {
124
- graphStore.setScale(zoomValue.value)
125
- emit('scale-changed', zoomValue.value)
143
+ const handleScaleChange = (scale: number) => {
144
+ graphStore.setScale(scale)
145
+ emit('scale-changed', scale)
126
146
  }
127
147
 
128
148
  // 处理放大按钮点击
129
149
  const handleZoomIn = () => {
150
+ // ZoomSlider组件已经处理了内部逻辑,这里只需要触发外部事件
130
151
  const newScale = Math.min(currentScale.value + 0.1, 3)
131
152
  graphStore.setScale(newScale)
132
153
  emit('scale-changed', newScale)
@@ -134,6 +155,7 @@ const handleZoomIn = () => {
134
155
 
135
156
  // 处理缩小按钮点击
136
157
  const handleZoomOut = () => {
158
+ // ZoomSlider组件已经处理了内部逻辑,这里只需要触发外部事件
137
159
  const newScale = Math.max(currentScale.value - 0.1, 0.1)
138
160
  graphStore.setScale(newScale)
139
161
  emit('scale-changed', newScale)
@@ -187,12 +209,14 @@ const handleNameClick = (shape: Shape, event: MouseEvent) => {
187
209
 
188
210
  // 处理图形点击事件
189
211
  const handleShapeClick = (shape: Shape, event: MouseEvent) => {
190
- graphStore.selectShape(shape)
212
+ return guardOperate(async () => {
213
+ graphStore.selectShape(shape)
214
+ })
191
215
  }
192
216
 
193
217
  // 处理编辑名称事件
194
- const handleEditName = (shape: Shape, newName: string) => {
195
- emit('shapes-edit-name', { shape, newName })
218
+ const handleEditName = (shape: Shape, newName: string, oldName: string) => {
219
+ emit('shapes-edit-name', { shape, newName, oldName })
196
220
  }
197
221
 
198
222
  // 处理连接点位置更新
@@ -209,6 +233,10 @@ const handleConnectEnd = (connectionData: { sourceId: string; targetId: string;
209
233
  console.log('连接结束事件已传递给父组件:', connectionData);
210
234
  }
211
235
 
236
+ const handleObjectFlowConnectEnd = (connectionData: { connectionData: { sourceId: string; targetId: string; sourcePoint: { x: number; y: number }; targetPoint: { x: number; y: number }; waypoints: Array<{ x: number; y: number }> }, outputPinBounds: { x: number; y: number; width: number; height: number }, inputPinBounds: { x: number; y: number; width: number; height: number } }) => {
237
+ emit('object-flow-connect-end', connectionData);
238
+ }
239
+
212
240
  // 处理双击图表事件
213
241
  const handleDiagramDoubleClick = (data: any) => {
214
242
  emit('diagramDoubleClick', data);
@@ -247,38 +275,48 @@ const handleEdgeClick = (shape: Shape, event: MouseEvent) => {
247
275
  interactionLayerRef.value.handleEdgeClick(edgeShape, event);
248
276
  }
249
277
  }
278
+
279
+ // 处理所在图表弹窗位置信息
280
+ const handleLocateChartPosition = (position: { x: number, y: number }) => {
281
+ tooltipX.value = position.x;
282
+ tooltipY.value = position.y;
283
+ tooltipVisible.value = true;
284
+ }
285
+
250
286
  const handleActionButtonAdd = (shape: Shape) => {
251
287
  emit('action-button-add', shape);
252
288
  }
253
289
 
254
290
  // 处理鼠标滚轮事件,实现缩放功能
255
291
  const handleWheel = (event: WheelEvent) => {
256
- // 只有按住Ctrl键时才执行缩放
257
- if (!event.ctrlKey && !event.metaKey) {
258
- // 不按住Ctrl键时,允许默认的滚轮行为(滚动)
259
- return;
260
- }
292
+ return guardOperate(async () => {
293
+ // 只有按住Ctrl键时才执行缩放
294
+ if (!event.ctrlKey && !event.metaKey) {
295
+ // 不按住Ctrl键时,允许默认的滚轮行为(滚动)
296
+ return;
297
+ }
261
298
 
262
- // 阻止默认行为,避免页面缩放
263
- event.preventDefault();
299
+ // 阻止默认行为,避免页面缩放
300
+ event.preventDefault();
264
301
 
265
- // 使用normalize-wheel-es标准化滚轮事件
266
- const normalized = normalizeWheel(event);
302
+ // 使用normalize-wheel-es标准化滚轮事件
303
+ const normalized = normalizeWheel(event);
267
304
 
268
- // 计算缩放比例增量
269
- const zoomFactor = 0.01;
270
- const delta = normalized.pixelY > 0 ? -zoomFactor : zoomFactor;
305
+ // 计算缩放比例增量
306
+ const zoomFactor = 0.01;
307
+ const delta = normalized.pixelY > 0 ? -zoomFactor : zoomFactor;
271
308
 
272
- // 获取当前缩放比例并计算新的缩放比例
273
- // getScale默认使用activeDiagramId
274
- const currentScale = graphStore.getScale();
275
- const newScale = currentScale + delta;
309
+ // 获取当前缩放比例并计算新的缩放比例
310
+ // getScale默认使用activeDiagramId
311
+ const currentScale = graphStore.getScale();
312
+ const newScale = currentScale + delta;
276
313
 
277
- // 设置新的缩放比例,默认使用activeDiagramId
278
- graphStore.setScale(newScale);
314
+ // 设置新的缩放比例,默认使用activeDiagramId
315
+ graphStore.setScale(newScale);
279
316
 
280
- // 通知父组件缩放变化
281
- emit('scale-changed', newScale);
317
+ // 通知父组件缩放变化
318
+ emit('scale-changed', newScale);
319
+ })
282
320
  }
283
321
 
284
322
  const updateShapes = (shapes: Shape[]) => {
@@ -376,17 +414,26 @@ watch(
376
414
  )
377
415
  // 把 referentialAttributeModel + pins 合并后存进 store
378
416
  watch(
379
- () => [props.referentialAttributeModel, props.pins,props.ports],
417
+ () => [props.referentialAttributeModel, props.pins, props.ports],
380
418
  ([referentialAttributeModel, pins]) => {
381
419
  const refArr = referentialAttributeModel ?? []
382
420
  const pinArr = pins ?? []
383
- const portArr = props.ports ?? []
421
+ const portArr = props.ports ?? []
384
422
  graphStore.pinsTypes = pinArr
385
423
  graphStore.portsTypes = portArr
386
- graphStore.ownerRequiredShapeKeys = [...refArr, ...pinArr,...portArr]
424
+ graphStore.ownerRequiredShapeKeys = [...refArr, ...pinArr, ...portArr]
387
425
  },
388
426
  { immediate: true }
389
427
  )
428
+ watch(
429
+ () => props.canOperate,
430
+ (val) => {
431
+ graphStore.canOperate = val ?? false
432
+ },
433
+ {
434
+ immediate: true,
435
+ }
436
+ )
390
437
  onMounted(() => {
391
438
  initShapes()
392
439
  document.addEventListener('keydown', (e) => {
@@ -396,6 +443,8 @@ onMounted(() => {
396
443
  }
397
444
  });
398
445
 
446
+ // 监听所在图表弹窗位置信息事件
447
+ eventBus.on('locate-chart-position', handleLocateChartPosition)
399
448
  })
400
449
 
401
450
  onUnmounted(() => {
@@ -405,6 +454,9 @@ onUnmounted(() => {
405
454
  graphStore.selectedIds = []
406
455
  }
407
456
  });
457
+
458
+ // 移除所在图表弹窗位置信息事件监听器
459
+ eventBus.off('locate-chart-position', handleLocateChartPosition)
408
460
  })
409
461
 
410
462
  defineExpose({
@@ -453,105 +505,21 @@ defineExpose({
453
505
  position: absolute;
454
506
  }
455
507
 
456
- /* 缩放条样式 */
457
- .zoom-bar {
458
- position: absolute;
459
- bottom: 0;
460
- right: 0;
461
- left: 0;
462
- width: 100%;
463
- height: 24px;
464
- display: flex;
465
- align-items: center;
466
- justify-content: flex-end;
467
- background: white;
468
- border-top: 1px solid #e0e0e0;
469
- box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.05);
470
- z-index: 1000;
471
- gap: 6px;
472
- padding: 0 10px;
473
- }
474
-
508
+ /* 缩放百分比显示 */
475
509
  .zoom-level {
510
+ position: absolute;
511
+ bottom: 30px;
512
+ right: 15px;
476
513
  font-size: 10px;
477
514
  font-weight: 500;
478
515
  min-width: 35px;
479
516
  text-align: center;
480
517
  color: #333;
518
+ background: rgba(255, 255, 255, 0.9);
519
+ padding: 2px 6px;
520
+ border-radius: 3px;
521
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
481
522
  }
482
523
 
483
- .zoom-slider {
484
- width: 150px;
485
- height: 100%;
486
- display: flex;
487
- align-items: center;
488
- justify-content: center;
489
- }
490
-
491
- .zoom-slider input[type="range"] {
492
- width: 100%;
493
- height: 2px;
494
- border-radius: 1px;
495
- background: #e0e0e0;
496
- outline: none;
497
- -webkit-appearance: none;
498
- margin: 0;
499
- }
500
-
501
- .zoom-slider input[type="range"]::-webkit-slider-thumb {
502
- -webkit-appearance: none;
503
- appearance: none;
504
- width: 10px;
505
- height: 10px;
506
- border-radius: 50%;
507
- background: #1890ff;
508
- cursor: pointer;
509
- transition: all 0.2s;
510
- }
511
-
512
- .zoom-slider input[type="range"]::-webkit-slider-thumb:hover {
513
- background: #40a9ff;
514
- transform: scale(1.1);
515
- }
516
-
517
- .zoom-slider input[type="range"]::-moz-range-thumb {
518
- width: 10px;
519
- height: 10px;
520
- border-radius: 50%;
521
- background: #1890ff;
522
- cursor: pointer;
523
- border: none;
524
- transition: all 0.2s;
525
- }
526
-
527
- .zoom-slider input[type="range"]::-moz-range-thumb:hover {
528
- background: #40a9ff;
529
- transform: scale(1.1);
530
- }
531
-
532
- .zoom-button {
533
- width: 18px;
534
- height: 18px;
535
- display: flex;
536
- align-items: center;
537
- justify-content: center;
538
- border: 1px solid #e0e0e0;
539
- border-radius: 2px;
540
- background: white;
541
- cursor: pointer;
542
- font-size: 10px;
543
- font-weight: 600;
544
- color: #333;
545
- transition: all 0.2s;
546
- }
547
-
548
- .zoom-button:hover {
549
- background: #f5f5f5;
550
- border-color: #1890ff;
551
- color: #1890ff;
552
- }
553
524
 
554
- .zoom-button:active {
555
- background: #e6f7ff;
556
- }
557
525
  </style>
File without changes