刘光辉
9 小时以前 0dfe84494048ce27ba8449831782128412d3eb13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { Disposable, ICommandService, Inject, IUniverInstanceService, UniverInstanceType, Workbook } from '@univerjs/core';
import { IDrawingManagerService } from '@univerjs/drawing';
import { DeviceInputEventType, IRenderManagerService } from '@univerjs/engine-render';
import { SheetsSelectionsService } from '@univerjs/sheets';
import { SheetCanvasFloatDomManagerService } from '@univerjs/sheets-drawing-ui';
import { attachRangeWithCoord, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
 
import { DefaultFloatImageHeight, DefaultFloatImageOption, DefaultFloatImageWidth, JnpfCommandIds, JnpfUniverFloatImageKey } from '../utils/define';
import { buildUUID } from '../utils/uuid';
 
export class JnpfSheetsFloatImageService extends Disposable {
  private _focusDrawingId: null | string = null;
  private _piniaStoreId: null | string = null;
 
  private readonly defaultPosition = { endX: DefaultFloatImageWidth, endY: DefaultFloatImageHeight, startX: 100, startY: 100 };
 
  constructor(
    @IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService,
    @ICommandService private readonly _commandService: ICommandService,
    @IRenderManagerService private readonly _renderManagerService: IRenderManagerService,
    @IDrawingManagerService private readonly _drawingManagerService: IDrawingManagerService,
    @Inject(SheetCanvasFloatDomManagerService) private readonly _sheetCanvasFloatDomManagerService: SheetCanvasFloatDomManagerService,
    @Inject(SheetsSelectionsService) private readonly _selectionManagerService: SheetsSelectionsService,
  ) {
    super();
 
    this._subscribeToFocusEvents();
  }
 
  // 清空焦点对象的id
  public clearFocusDrawingId() {
    if (!this._focusDrawingId) {
      return;
    }
 
    this._focusDrawingId = null;
  }
 
  // 创建并插入悬浮图片DOM
  public insertFloatImage() {
    this._commandService
      .executeCommand('sheet.operation.set-cell-edit-visible', {
        _eventType: DeviceInputEventType.PointerUp,
        visible: false,
      })
      .then();
 
    const initPosition = this._calculateInitPosition();
    const domId = `float_image_${buildUUID()}`;
 
    const addResult = this._sheetCanvasFloatDomManagerService?.addFloatDomToPosition({
      allowTransform: true,
      componentKey: JnpfUniverFloatImageKey,
      initPosition,
      data: {
        id: domId,
        piniaStoreId: this._piniaStoreId,
      },
    });
 
    if (!addResult) {
      return;
    }
 
    const newParams = {
      domId,
      drawingId: addResult.id,
      imageType: 'BASE64',
      option: JSON.parse(JSON.stringify(DefaultFloatImageOption)),
    };
 
    this._commandService.executeCommand(JnpfCommandIds?.insertedFloatImage, newParams).then();
  }
 
  // 存入store的id
  public savePiniaStoreId(data: string) {
    this._piniaStoreId = data;
  }
 
  // 计算初始位置
  private _calculateInitPosition() {
    // 获取当前单元格数据
    const unit = this._univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET);
    if (!unit) {
      console.warn('警告:未找到单元。使用默认位置 (100, 100)。');
      return this.defaultPosition;
    }
 
    const unitId = unit!.getUnitId();
    const currentSelections = this._selectionManagerService.getCurrentSelections();
    const firstSelection = currentSelections?.[0] ?? {};
    if (!firstSelection?.range) {
      console.warn('警告:未找到选择范围。使用默认位置 (100, 100)。');
      return this.defaultPosition;
    }
 
    // 获取当前表格骨架信息
    const sheetSkeletonService = this._renderManagerService.getRenderById(unitId)?.with(SheetSkeletonManagerService);
    const currentSkeleton = sheetSkeletonService?.getCurrent()?.skeleton;
    if (!currentSkeleton) {
      console.warn('警告:未找到骨架。使用默认位置 (100, 100)。');
      return this.defaultPosition;
    }
 
    // 解构表格尺寸信息
    const { columnHeaderHeight = 0, columnTotalWidth = 0, rowHeaderWidth = 0, rowTotalHeight = 0 } = currentSkeleton;
    const columnScreenTotalWidth = columnTotalWidth + rowHeaderWidth;
    const columnScreenTotalHeight = rowTotalHeight + columnHeaderHeight;
 
    // 获取范围信息并计算坐标
    const rangeInfo = attachRangeWithCoord(currentSkeleton, firstSelection.range) || { startX: 0, startY: 0 };
    const { startX: rangeStartX, startY: rangeStartY } = rangeInfo;
 
    // 计算图表的边界坐标
    const startX = Math.min(rangeStartX + DefaultFloatImageWidth, columnScreenTotalWidth) - DefaultFloatImageWidth;
    const endX = Math.min(rangeStartX + DefaultFloatImageWidth, columnScreenTotalWidth);
    const startY = Math.min(rangeStartY + DefaultFloatImageHeight, columnScreenTotalHeight) - DefaultFloatImageHeight;
    const endY = Math.min(rangeStartY + DefaultFloatImageHeight, columnScreenTotalHeight);
 
    return { endX, endY, startX, startY };
  }
 
  // 订阅图表的焦点事件
  private _subscribeToFocusEvents() {
    this.disposeWithMe(
      this._drawingManagerService.focus$.subscribe(params => {
        if (params && params?.length) {
          const firstParam = (params?.[0] ?? {}) as any;
          const { componentKey, drawingId } = firstParam;
 
          if (drawingId !== this._focusDrawingId && componentKey === JnpfUniverFloatImageKey) {
            this._focusDrawingId = drawingId;
 
            this._commandService?.executeCommand(JnpfCommandIds.focusFloatImage, firstParam);
          }
        }
      }),
    );
  }
}