@gct-paas/word 0.1.73-patch.2 → 0.1.73-patch.4

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.
@@ -20,6 +20,8 @@ export declare function computeImageDisplaySize(natural: ImageSize, opts?: Image
20
20
  * 在目标框内等比缩放(contain),不压缩、不拉伸
21
21
  */
22
22
  export declare function computeContainDisplaySize(natural: ImageSize, box: ImageSize): ImageSize;
23
+ /** 同步取无图签名缓存(布局重建时可避免先闪占位再异步补图) */
24
+ export declare function getCachedSignatureImage(name: string, width?: number, height?: number, time?: number | string): HTMLImageElement | null;
23
25
  /**
24
26
  * 创建无图签名兜底图(用户名 + 电子签名 + 验证日期)
25
27
  * 按字段宽高绘制,显示框设多大,字就按多大排
@@ -25,7 +25,13 @@ export declare class WtblCalculation {
25
25
  */
26
26
  private static processBounded;
27
27
  /**
28
- * 处理 boundedItem 数据
28
+ * 按 itemRegion.id 查找嵌套的数据分组 / 动态关联区域
29
+ * (itemRegion 不在 table.regions 顶层,不能用 findRegionById)
30
+ */
31
+ private static findItemRegionById;
32
+ private static applyBoundsToItemRegion;
33
+ /**
34
+ * 处理 boundedItem 数据(更新父级 bounded 的 itemRegion 边界)
29
35
  */
30
36
  private static processBoundedItem;
31
37
  /**
@@ -33,7 +39,7 @@ export declare class WtblCalculation {
33
39
  */
34
40
  private static processCheckTable;
35
41
  /**
36
- * 处理 dataGroup2D 数据
42
+ * 处理 dataGroup2D 数据(更新检验表 / 二维表上的 itemRegion 边界)
37
43
  */
38
44
  private static processDataGroup2D;
39
45
  }
@@ -9,11 +9,23 @@ export declare class WtblRowColumnOps {
9
9
  /** 仅外表需要做「删除行/列/表时联动删除嵌套表」 */
10
10
  private static detachNestedTablesFromOuterTable;
11
11
  /**
12
- * 新单元格同步引用信息
13
- * refCell: 参考单元格 (above | left)
14
- * nextRefCell: 后参考单元格 (below | right ),如果传入,需要跟 refCell 比对一致后同步
12
+ * 新单元格同步引用信息(mergeId / subTable / subTableItem / header)
13
+ *
14
+ * 必须两侧参考单元格都存在,且对应字段一致,才写入新格。
15
+ * 单侧缺失(表边界、子表外侧空行)不同步,避免检验表等 region
16
+ * 在「上一行/下一行插入」时被错误扩大,进而触发重叠校验误报。
15
17
  */
16
18
  private static syncRefInfo;
19
+ /**
20
+ * 在 insertIndex 处插入一行后,将落在该行及以下的 region / itemRegion 行号整体 +1。
21
+ * 否则仅靠单元格标记回写时,动态关联 itemRegion 若未能匹配 id,边界会留在原行,
22
+ * 设计端字段与背景框就不会随检验表下移。
23
+ */
24
+ private static shiftRegionsForRowInsert;
25
+ /**
26
+ * 在 insertIndex 处插入一列后,将落在该列及右侧的 region / itemRegion 列号整体 +1。
27
+ */
28
+ private static shiftRegionsForColInsert;
17
29
  /**
18
30
  * 在指定行位置插入新行
19
31
  */
@@ -1,6 +1,7 @@
1
1
  import { CheckTableItemInfosPayload, CheckTableRegionRef } from '../types';
2
2
  /**
3
3
  * 按已扫描的检验表 region 并行拉取检验项详情。
4
+ * @param instanceId 真实填报实例 id;设计态 / 模拟填报应传空字符串(默认数据源将跳过请求)
4
5
  * @returns infosMap / countMap(count 至少为 1,用于占位行)
5
6
  */
6
7
  export declare function fetchCheckItemsForRegions(instanceId: string, regions: CheckTableRegionRef[]): Promise<{
package/dist/index.es.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! @gct-paas/word v0.1.73-patch.2 */
1
+ /*! @gct-paas/word v0.1.73-patch.4 */
2
2
  import { Fragment, Suspense, Teleport, Transition, TransitionGroup, cloneVNode, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createTextVNode, createVNode, defineAsyncComponent, defineComponent, getCurrentInstance, getCurrentScope, guardReactiveProps, h, inject, isRef, isVNode, markRaw, mergeModels, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onBeforeMount, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, openBlock, provide, reactive, readonly, ref, render, renderList, renderSlot, resolveComponent, resolveDynamicComponent, shallowRef, toDisplayString, toRaw, toRef, toValue, unref, useCssVars, useModel, useSlots, vModelText, vShow, watch, watchEffect, withCtx, withDirectives, withKeys, withModifiers } from "vue";
3
3
  import FloatingVue, { PopperWrapper } from "floating-vue";
4
4
  import VueKonva from "vue-konva";
@@ -92458,16 +92458,16 @@ async function fetchCustomCheckDsData(customCheckDsItems) {
92458
92458
  return toPayload(await callBizService(CUSTOM_API, { ids: customCheckDsItems.join(",") }));
92459
92459
  }
92460
92460
  async function fetchOneRegionInfo(instanceId, region) {
92461
- if (!instanceId) return EMPTY_INFO;
92462
92461
  const props = region.props ?? {};
92463
92462
  const checkDsType = props.checkDsType;
92464
92463
  const customCheckDsItems = Array.isArray(props.customCheckDsItems) ? props.customCheckDsItems : [];
92465
- const info = checkDsType === CheckDsTypeEnum.CUSTOM ? await fetchCustomCheckDsData(customCheckDsItems) : await fetchCheckDsDataForTable(instanceId);
92464
+ const info = checkDsType === CheckDsTypeEnum.CUSTOM ? await fetchCustomCheckDsData(customCheckDsItems) : instanceId ? await fetchCheckDsDataForTable(instanceId) : EMPTY_INFO;
92466
92465
  for (const item of info.data) delete item.id_;
92467
92466
  return info;
92468
92467
  }
92469
92468
  /**
92470
92469
  * 按已扫描的检验表 region 并行拉取检验项详情。
92470
+ * @param instanceId 真实填报实例 id;设计态 / 模拟填报应传空字符串(默认数据源将跳过请求)
92471
92471
  * @returns infosMap / countMap(count 至少为 1,用于占位行)
92472
92472
  */
92473
92473
  async function fetchCheckItemsForRegions(instanceId, regions) {
@@ -100569,11 +100569,12 @@ var init_BoundedRegion = __esmMin((() => {
100569
100569
  widgetMeta: json.widgetMeta
100570
100570
  });
100571
100571
  if (json.itemRegion) {
100572
- var _json$itemRegion, _json$itemRegion2;
100572
+ var _json$itemRegion, _json$itemRegion2, _json$itemRegion3;
100573
100573
  region.itemRegion = new BoundedItemRegion({
100574
100574
  table,
100575
- start: (_json$itemRegion = json.itemRegion) === null || _json$itemRegion === void 0 ? void 0 : _json$itemRegion.start,
100576
- end: (_json$itemRegion2 = json.itemRegion) === null || _json$itemRegion2 === void 0 ? void 0 : _json$itemRegion2.end,
100575
+ id: (_json$itemRegion = json.itemRegion) === null || _json$itemRegion === void 0 ? void 0 : _json$itemRegion.id,
100576
+ start: (_json$itemRegion2 = json.itemRegion) === null || _json$itemRegion2 === void 0 ? void 0 : _json$itemRegion2.start,
100577
+ end: (_json$itemRegion3 = json.itemRegion) === null || _json$itemRegion3 === void 0 ? void 0 : _json$itemRegion3.end,
100577
100578
  parent: region
100578
100579
  });
100579
100580
  }
@@ -100677,11 +100678,12 @@ var init_LinkSubTableRegion = __esmMin((() => {
100677
100678
  }
100678
100679
  static restoreItemRegion(region, json, table) {
100679
100680
  if (json.itemRegion) {
100680
- var _json$itemRegion, _json$itemRegion2;
100681
+ var _json$itemRegion, _json$itemRegion2, _json$itemRegion3;
100681
100682
  region.itemRegion = new DataGroup2DRegion({
100682
100683
  table,
100683
- start: (_json$itemRegion = json.itemRegion) === null || _json$itemRegion === void 0 ? void 0 : _json$itemRegion.start,
100684
- end: (_json$itemRegion2 = json.itemRegion) === null || _json$itemRegion2 === void 0 ? void 0 : _json$itemRegion2.end,
100684
+ id: (_json$itemRegion = json.itemRegion) === null || _json$itemRegion === void 0 ? void 0 : _json$itemRegion.id,
100685
+ start: (_json$itemRegion2 = json.itemRegion) === null || _json$itemRegion2 === void 0 ? void 0 : _json$itemRegion2.start,
100686
+ end: (_json$itemRegion3 = json.itemRegion) === null || _json$itemRegion3 === void 0 ? void 0 : _json$itemRegion3.end,
100685
100687
  parent: region
100686
100688
  });
100687
100689
  }
@@ -100918,19 +100920,50 @@ var init_RowColumnOps = __esmMin((() => {
100918
100920
  table.collectNestedTables().forEach((nested) => nested.remove());
100919
100921
  }
100920
100922
  /**
100921
- * 新单元格同步引用信息
100922
- * refCell: 参考单元格 (above | left)
100923
- * nextRefCell: 后参考单元格 (below | right ),如果传入,需要跟 refCell 比对一致后同步
100923
+ * 新单元格同步引用信息(mergeId / subTable / subTableItem / header)
100924
+ *
100925
+ * 必须两侧参考单元格都存在,且对应字段一致,才写入新格。
100926
+ * 单侧缺失(表边界、子表外侧空行)不同步,避免检验表等 region
100927
+ * 在「上一行/下一行插入」时被错误扩大,进而触发重叠校验误报。
100924
100928
  */
100925
- static syncRefInfo(newCell, refCell, nextRefCell) {
100929
+ static syncRefInfo(newCell, sideA, sideB) {
100930
+ if (!sideA || !sideB) return;
100926
100931
  WTC_REF_KEYS.forEach((key) => {
100927
- const refValue = refCell[key];
100932
+ const refValue = sideA[key];
100928
100933
  if (!refValue) return;
100929
- if (nextRefCell && JSON.stringify(nextRefCell[key]) !== JSON.stringify(refValue)) return;
100934
+ if (JSON.stringify(sideB[key]) !== JSON.stringify(refValue)) return;
100930
100935
  newCell[key] = refValue;
100931
100936
  });
100932
100937
  }
100933
100938
  /**
100939
+ * 在 insertIndex 处插入一行后,将落在该行及以下的 region / itemRegion 行号整体 +1。
100940
+ * 否则仅靠单元格标记回写时,动态关联 itemRegion 若未能匹配 id,边界会留在原行,
100941
+ * 设计端字段与背景框就不会随检验表下移。
100942
+ */
100943
+ static shiftRegionsForRowInsert(table, insertIndex) {
100944
+ for (const region of table.regions) {
100945
+ if (region.start.row >= insertIndex) region.start.row += 1;
100946
+ if (region.end.row >= insertIndex) region.end.row += 1;
100947
+ const itemRegion = region.itemRegion;
100948
+ if (!itemRegion) continue;
100949
+ if (itemRegion.start.row >= insertIndex) itemRegion.start.row += 1;
100950
+ if (itemRegion.end.row >= insertIndex) itemRegion.end.row += 1;
100951
+ }
100952
+ }
100953
+ /**
100954
+ * 在 insertIndex 处插入一列后,将落在该列及右侧的 region / itemRegion 列号整体 +1。
100955
+ */
100956
+ static shiftRegionsForColInsert(table, insertIndex) {
100957
+ for (const region of table.regions) {
100958
+ if (region.start.col >= insertIndex) region.start.col += 1;
100959
+ if (region.end.col >= insertIndex) region.end.col += 1;
100960
+ const itemRegion = region.itemRegion;
100961
+ if (!itemRegion) continue;
100962
+ if (itemRegion.start.col >= insertIndex) itemRegion.start.col += 1;
100963
+ if (itemRegion.end.col >= insertIndex) itemRegion.end.col += 1;
100964
+ }
100965
+ }
100966
+ /**
100934
100967
  * 在指定行位置插入新行
100935
100968
  */
100936
100969
  static insertRowAt(table, index) {
@@ -100944,6 +100977,7 @@ var init_RowColumnOps = __esmMin((() => {
100944
100977
  this.syncRefInfo(cell, above, below);
100945
100978
  });
100946
100979
  table.insertChildAt(index, newRow);
100980
+ this.shiftRegionsForRowInsert(table, index);
100947
100981
  } });
100948
100982
  }
100949
100983
  /**
@@ -100953,11 +100987,13 @@ var init_RowColumnOps = __esmMin((() => {
100953
100987
  const refRow = table.getChildAt(index);
100954
100988
  if (!refRow) return;
100955
100989
  table.runConsistencyMutation({ mutate: () => {
100990
+ const above = table.rows[index - 1];
100956
100991
  const newRow = Wtr.fromTemplate(table.colWidths || []);
100957
100992
  newRow.children.forEach((cell, cellIndex) => {
100958
- this.syncRefInfo(cell, refRow.cells[cellIndex]);
100993
+ this.syncRefInfo(cell, above === null || above === void 0 ? void 0 : above.cells[cellIndex], refRow.cells[cellIndex]);
100959
100994
  });
100960
100995
  table.insertBefore(refRow, newRow);
100996
+ this.shiftRegionsForRowInsert(table, index);
100961
100997
  } });
100962
100998
  }
100963
100999
  /**
@@ -100967,11 +101003,13 @@ var init_RowColumnOps = __esmMin((() => {
100967
101003
  const refRow = table.getChildAt(index);
100968
101004
  if (!refRow) return;
100969
101005
  table.runConsistencyMutation({ mutate: () => {
101006
+ const below = table.rows[index + 1];
100970
101007
  const newRow = Wtr.fromTemplate(table.colWidths || []);
100971
101008
  newRow.children.forEach((cell, cellIndex) => {
100972
- this.syncRefInfo(cell, refRow.cells[cellIndex]);
101009
+ this.syncRefInfo(cell, refRow.cells[cellIndex], below === null || below === void 0 ? void 0 : below.cells[cellIndex]);
100973
101010
  });
100974
101011
  table.insertAfter(refRow, newRow);
101012
+ this.shiftRegionsForRowInsert(table, index + 1);
100975
101013
  } });
100976
101014
  }
100977
101015
  /**
@@ -100988,6 +101026,7 @@ var init_RowColumnOps = __esmMin((() => {
100988
101026
  this.syncRefInfo(newCell, left, right);
100989
101027
  }
100990
101028
  if (table.colWidths) table.colWidths.splice(index, 0, colWidth);
101029
+ this.shiftRegionsForColInsert(table, index);
100991
101030
  } });
100992
101031
  }
100993
101032
  /**
@@ -100997,13 +101036,15 @@ var init_RowColumnOps = __esmMin((() => {
100997
101036
  table.runConsistencyMutation({ mutate: () => {
100998
101037
  const colWidth = DEFAULT_WIDTH;
100999
101038
  for (const row of table.rows) {
101000
- const refCell = row.cells[index];
101001
- if (!refCell) continue;
101039
+ const right = row.cells[index];
101040
+ if (!right) continue;
101041
+ const left = row.cells[index - 1];
101002
101042
  const newCell = Wtc.fromTemplate(colWidth);
101003
- this.syncRefInfo(newCell, refCell);
101043
+ this.syncRefInfo(newCell, left, right);
101004
101044
  row.insertChildAt(index, newCell);
101005
101045
  }
101006
101046
  if (table.colWidths) table.colWidths.splice(index, 0, colWidth);
101047
+ this.shiftRegionsForColInsert(table, index);
101007
101048
  } });
101008
101049
  }
101009
101050
  /**
@@ -101013,13 +101054,15 @@ var init_RowColumnOps = __esmMin((() => {
101013
101054
  table.runConsistencyMutation({ mutate: () => {
101014
101055
  const colWidth = DEFAULT_WIDTH;
101015
101056
  for (const row of table.rows) {
101016
- const refCell = row.cells[index];
101017
- if (!refCell) continue;
101057
+ const left = row.cells[index];
101058
+ if (!left) continue;
101059
+ const right = row.cells[index + 1];
101018
101060
  const newCell = Wtc.fromTemplate(colWidth);
101019
- this.syncRefInfo(newCell, refCell);
101061
+ this.syncRefInfo(newCell, left, right);
101020
101062
  row.insertChildAt(index + 1, newCell);
101021
101063
  }
101022
101064
  if (table.colWidths) table.colWidths.splice(index + 1, 0, colWidth);
101065
+ this.shiftRegionsForColInsert(table, index + 1);
101023
101066
  } });
101024
101067
  }
101025
101068
  /**
@@ -101590,19 +101633,36 @@ var init_Calculation = __esmMin((() => {
101590
101633
  }
101591
101634
  }
101592
101635
  /**
101593
- * 处理 boundedItem 数据
101636
+ * 按 itemRegion.id 查找嵌套的数据分组 / 动态关联区域
101637
+ * (itemRegion 不在 table.regions 顶层,不能用 findRegionById)
101638
+ */
101639
+ static findItemRegionById(table, itemId) {
101640
+ for (const region of table.regions) {
101641
+ if (region.type === "bounded") {
101642
+ const item = region.itemRegion;
101643
+ if ((item === null || item === void 0 ? void 0 : item.id) === itemId) return item;
101644
+ }
101645
+ if (isLinkSubTableType(region.type)) {
101646
+ const item = region.itemRegion;
101647
+ if ((item === null || item === void 0 ? void 0 : item.id) === itemId) return item;
101648
+ }
101649
+ }
101650
+ }
101651
+ static applyBoundsToItemRegion(itemRegion, bounds) {
101652
+ itemRegion.start.row = bounds.minRow;
101653
+ itemRegion.end.row = bounds.maxRow;
101654
+ itemRegion.start.col = bounds.minCol;
101655
+ itemRegion.end.col = bounds.maxCol;
101656
+ }
101657
+ /**
101658
+ * 处理 boundedItem 数据(更新父级 bounded 的 itemRegion 边界)
101594
101659
  */
101595
101660
  static processBoundedItem(table, boundedItemGroups) {
101596
101661
  for (const [groupId, positions] of boundedItemGroups.entries()) {
101597
101662
  if (positions.length === 0) continue;
101598
- const { minRow, maxRow, minCol, maxCol } = calculateGroupBounds(positions);
101599
- const region = table.findRegionById(groupId);
101600
- if (region && region.type === "bounded") {
101601
- region.start.row = minRow;
101602
- region.end.row = maxRow;
101603
- region.start.col = minCol;
101604
- region.end.col = maxCol;
101605
- }
101663
+ const itemRegion = this.findItemRegionById(table, groupId);
101664
+ if (!itemRegion) continue;
101665
+ this.applyBoundsToItemRegion(itemRegion, calculateGroupBounds(positions));
101606
101666
  }
101607
101667
  }
101608
101668
  /**
@@ -101622,19 +101682,14 @@ var init_Calculation = __esmMin((() => {
101622
101682
  }
101623
101683
  }
101624
101684
  /**
101625
- * 处理 dataGroup2D 数据
101685
+ * 处理 dataGroup2D 数据(更新检验表 / 二维表上的 itemRegion 边界)
101626
101686
  */
101627
101687
  static processDataGroup2D(table, dataGroup2DGroups) {
101628
101688
  for (const [groupId, positions] of dataGroup2DGroups.entries()) {
101629
101689
  if (positions.length === 0) continue;
101630
- const { minRow, maxRow, minCol, maxCol } = calculateGroupBounds(positions);
101631
- const region = table.findRegionById(groupId);
101632
- if (region && isLinkSubTableType(region.type)) {
101633
- region.start.row = minRow;
101634
- region.end.row = maxRow;
101635
- region.start.col = minCol;
101636
- region.end.col = maxCol;
101637
- }
101690
+ const itemRegion = this.findItemRegionById(table, groupId);
101691
+ if (!itemRegion) continue;
101692
+ this.applyBoundsToItemRegion(itemRegion, calculateGroupBounds(positions));
101638
101693
  }
101639
101694
  }
101640
101695
  };
@@ -105483,6 +105538,50 @@ function isTableNested(doc, tableId) {
105483
105538
  return (meta === null || meta === void 0 ? void 0 : meta.component) === BuiltinComponentTypeConst.TableCell;
105484
105539
  });
105485
105540
  }
105541
+ /**
105542
+ * 按合并单元格把选区列范围扩成完整矩形。
105543
+ *
105544
+ * 横向合并只能点到主格(tableCellIndex 为起点列),从上往下拖进合并区时
105545
+ * anchor/focus 往往同为起点列,右侧从格进不了选区。
105546
+ * 需把选中格所属合并区的完整 colspan 扩进 [colFrom, colTo]。
105547
+ */
105548
+ function expandColRangeForMergedCells(doc, tableLines, colFrom, colTo) {
105549
+ let from = colFrom;
105550
+ let to = colTo;
105551
+ for (let guard = 0; guard < 32; guard++) {
105552
+ let expanded = false;
105553
+ for (const line of tableLines) {
105554
+ const colCount = line.nextIds.length;
105555
+ for (let ci = from; ci <= to && ci < colCount; ci++) {
105556
+ const cellId = line.nextIds[ci];
105557
+ if (!cellId) continue;
105558
+ const cell = doc.layoutMapper.getLayoutNodeById(cellId);
105559
+ if (!cell) continue;
105560
+ let spanStart = ci;
105561
+ let spanEnd = ci;
105562
+ if (cell.mergeFromId) {
105563
+ const master = doc.layoutMapper.getLayoutNodeById(cell.mergeFromId);
105564
+ if (!master) continue;
105565
+ spanStart = ci - (cell.mergeRefColOffset ?? 0);
105566
+ spanEnd = spanStart + (master.colspan || 1) - 1;
105567
+ } else if ((cell.colspan || 1) > 1) spanEnd = ci + (cell.colspan || 1) - 1;
105568
+ else continue;
105569
+ const nextFrom = Math.min(from, Math.max(0, spanStart));
105570
+ const nextTo = Math.max(to, Math.min(colCount - 1, spanEnd));
105571
+ if (nextFrom !== from || nextTo !== to) {
105572
+ from = nextFrom;
105573
+ to = nextTo;
105574
+ expanded = true;
105575
+ }
105576
+ }
105577
+ }
105578
+ if (!expanded) break;
105579
+ }
105580
+ return {
105581
+ colFrom: from,
105582
+ colTo: to
105583
+ };
105584
+ }
105486
105585
  function findEnclosingTable(node) {
105487
105586
  let current = node;
105488
105587
  while (current) {
@@ -105685,43 +105784,46 @@ function getSelectLinesInfo(doc, selection, upgrade) {
105685
105784
  }
105686
105785
  }
105687
105786
  const rangeWidgetIds = [];
105688
- scopedSelectedLines.forEach((line) => {
105689
- if (line.type !== "tablerow") return;
105690
- if (tableMode === "cell-range") {
105787
+ if (tableMode === "cell-range") {
105788
+ const tableLines = scopedSelectedLines.filter((line) => line.type === "tablerow");
105789
+ if (tableLines.length > 0) {
105790
+ const firstLine = tableLines[0];
105691
105791
  const startCI = typeof scopedStartCellIndex === "number" ? scopedStartCellIndex : 0;
105692
- const endCI = typeof scopedEndCellIndex === "number" ? scopedEndCellIndex : typeof focusClampToLast === "boolean" ? focusClampToLast ? (line.nextIds.length ?? 1) - 1 : 0 : typeof scopedStartCellIndex === "number" ? scopedStartCellIndex : (line.nextIds.length ?? 1) - 1;
105693
- const colFrom = Math.min(startCI, endCI);
105694
- const colTo = Math.max(startCI, endCI);
105695
- for (let ci = colFrom; ci <= colTo; ci++) {
105792
+ const endCI = typeof scopedEndCellIndex === "number" ? scopedEndCellIndex : typeof focusClampToLast === "boolean" ? focusClampToLast ? (firstLine.nextIds.length ?? 1) - 1 : 0 : typeof scopedStartCellIndex === "number" ? scopedStartCellIndex : (firstLine.nextIds.length ?? 1) - 1;
105793
+ let colFrom = Math.min(startCI, endCI);
105794
+ let colTo = Math.max(startCI, endCI);
105795
+ ({colFrom, colTo} = expandColRangeForMergedCells(doc, tableLines, colFrom, colTo));
105796
+ for (const line of tableLines) for (let ci = colFrom; ci <= colTo; ci++) {
105696
105797
  const cellId = line.nextIds[ci];
105697
105798
  if (cellId) rangeWidgetIds.push(cellId);
105698
105799
  }
105699
- } else if (tableMode === "cell-full") {
105700
- var _start$line4, _end$line3;
105701
- const startCellId = (_start$line4 = start.line) === null || _start$line4 === void 0 ? void 0 : _start$line4.tableCellId;
105702
- const endCellId = (_end$line3 = end.line) === null || _end$line3 === void 0 ? void 0 : _end$line3.tableCellId;
105703
- if (startCellId && startCellId === endCellId) {
105704
- var _start$line5;
105705
- const cell = doc.layoutMapper.getLayoutNodeById(startCellId);
105706
- const table = doc.layoutMapper.getLayoutNodeById((_start$line5 = start.line) === null || _start$line5 === void 0 ? void 0 : _start$line5.tableId);
105707
- if (cell && table) {
105708
- var _start$line6, _start$line7;
105709
- const startRowIdx = (_start$line6 = start.line) === null || _start$line6 === void 0 ? void 0 : _start$line6.tableRowIndex;
105710
- const startColIdx = (_start$line7 = start.line) === null || _start$line7 === void 0 ? void 0 : _start$line7.tableCellIndex;
105711
- const rowspan = cell.rowspan || 1;
105712
- const colspan = cell.colspan || 1;
105713
- table.forEachCell({
105714
- startRowIdx,
105715
- startColIdx,
105716
- endRowIdx: startRowIdx + rowspan - 1,
105717
- endColIdx: startColIdx + colspan - 1,
105718
- callback: (c) => rangeWidgetIds.push(c.id)
105719
- });
105720
- }
105800
+ }
105801
+ } else if (tableMode === "cell-full") {
105802
+ var _start$line4, _end$line3;
105803
+ const startCellId = (_start$line4 = start.line) === null || _start$line4 === void 0 ? void 0 : _start$line4.tableCellId;
105804
+ const endCellId = (_end$line3 = end.line) === null || _end$line3 === void 0 ? void 0 : _end$line3.tableCellId;
105805
+ if (startCellId && startCellId === endCellId) {
105806
+ var _start$line5;
105807
+ const cell = doc.layoutMapper.getLayoutNodeById(startCellId);
105808
+ const table = doc.layoutMapper.getLayoutNodeById((_start$line5 = start.line) === null || _start$line5 === void 0 ? void 0 : _start$line5.tableId);
105809
+ if (cell && table) {
105810
+ var _start$line6, _start$line7;
105811
+ const startRowIdx = (_start$line6 = start.line) === null || _start$line6 === void 0 ? void 0 : _start$line6.tableRowIndex;
105812
+ const startColIdx = (_start$line7 = start.line) === null || _start$line7 === void 0 ? void 0 : _start$line7.tableCellIndex;
105813
+ const rowspan = cell.rowspan || 1;
105814
+ const colspan = cell.colspan || 1;
105815
+ table.forEachCell({
105816
+ startRowIdx,
105817
+ startColIdx,
105818
+ endRowIdx: startRowIdx + rowspan - 1,
105819
+ endColIdx: startColIdx + colspan - 1,
105820
+ callback: (c) => rangeWidgetIds.push(c.id)
105821
+ });
105721
105822
  }
105722
- } else if (tableMode === "mixed") {
105723
- for (const cellId of line.nextIds) if (cellId) rangeWidgetIds.push(cellId);
105724
105823
  }
105824
+ } else if (tableMode === "mixed") scopedSelectedLines.forEach((line) => {
105825
+ if (line.type !== "tablerow") return;
105826
+ for (const cellId of line.nextIds) if (cellId) rangeWidgetIds.push(cellId);
105725
105827
  });
105726
105828
  return {
105727
105829
  normalized,
@@ -109533,6 +109635,34 @@ var init_InsertText = __esmMin((() => {
109533
109635
  //#endregion
109534
109636
  //#region src/core/command/commands/MergeCells.ts
109535
109637
  var MergeCells_exports = /* @__PURE__ */ __exportAll({ MergeCells: () => MergeCells });
109638
+ /**
109639
+ * 选区只包含「可视主格」时,补齐其 merge 区域内的从格。
109640
+ *
109641
+ * 横向合并后从格不渲染、不可点选,跨行再合并时选区往往只有各行主格(同一列)。
109642
+ * 若不展开,会把已有 colspan/rowspan 误判成部分重叠。
109643
+ */
109644
+ function expandSelectionToMergeRegions(table, selectedCells) {
109645
+ var _table$rows$;
109646
+ const selectedIds = new Set(selectedCells.map((cell) => cell.id));
109647
+ const mergeIds = new Set(selectedCells.map((cell) => cell.mergeId).filter((id) => !!id));
109648
+ const expanded = [];
109649
+ const colCount = ((_table$rows$ = table.rows[0]) === null || _table$rows$ === void 0 ? void 0 : _table$rows$.cells.length) ?? 0;
109650
+ if (colCount === 0 || table.rows.length === 0) return expanded;
109651
+ table.forEachCell({
109652
+ startRowIdx: 0,
109653
+ endRowIdx: table.rows.length - 1,
109654
+ startColIdx: 0,
109655
+ endColIdx: colCount - 1,
109656
+ callback: (cell, row, col) => {
109657
+ if (selectedIds.has(cell.id) || cell.mergeId && mergeIds.has(cell.mergeId)) expanded.push({
109658
+ cell,
109659
+ row,
109660
+ col
109661
+ });
109662
+ }
109663
+ });
109664
+ return expanded;
109665
+ }
109536
109666
  var MergeCells;
109537
109667
  var init_MergeCells = __esmMin((() => {
109538
109668
  init_CommandBase();
@@ -109550,66 +109680,41 @@ var init_MergeCells = __esmMin((() => {
109550
109680
  const selectedCells = models.map(({ model }) => model);
109551
109681
  const table = (_selectedCells$ = selectedCells[0]) === null || _selectedCells$ === void 0 ? void 0 : _selectedCells$.table;
109552
109682
  if (!table) return null;
109553
- const positions = selectedCells.map((cell) => {
109683
+ if (selectedCells.map((cell) => {
109554
109684
  var _cell$parent;
109555
109685
  return {
109556
109686
  cell,
109557
109687
  row: ((_cell$parent = cell.parent) === null || _cell$parent === void 0 ? void 0 : _cell$parent.getCurrentIndex()) ?? -1,
109558
109688
  col: cell.getCurrentIndex() ?? -1
109559
109689
  };
109560
- });
109561
- if (positions.some(({ row, col }) => row < 0 || col < 0)) throw new Error("Invalid table selection");
109562
- const minRow = Math.min(...positions.map((p) => p.row));
109563
- const maxRow = Math.max(...positions.map((p) => p.row));
109564
- const minCol = Math.min(...positions.map((p) => p.col));
109565
- const maxCol = Math.max(...positions.map((p) => p.col));
109566
- const rowSpan = maxRow - minRow + 1;
109567
- const colSpan = maxCol - minCol + 1;
109568
- const expectedCount = rowSpan * colSpan;
109569
- const selectedIds = new Set(selectedCells.map((cell) => cell.id));
109690
+ }).some(({ row, col }) => row < 0 || col < 0)) throw new Error("Invalid table selection");
109691
+ let minRow = 0;
109692
+ let maxRow = 0;
109693
+ let minCol = 0;
109694
+ let maxCol = 0;
109570
109695
  let topLeftCell;
109571
109696
  table.runConsistencyMutation({
109572
109697
  validate: () => {
109573
- if (selectedIds.size !== expectedCount) throw new Error("必须是完整矩形");
109574
- const mergeRoots = /* @__PURE__ */ new Map();
109698
+ const expanded = expandSelectionToMergeRegions(table, selectedCells);
109699
+ if (expanded.length === 0) throw new Error("Invalid table selection");
109700
+ minRow = Math.min(...expanded.map((p) => p.row));
109701
+ maxRow = Math.max(...expanded.map((p) => p.row));
109702
+ minCol = Math.min(...expanded.map((p) => p.col));
109703
+ maxCol = Math.max(...expanded.map((p) => p.col));
109704
+ const expectedCount = (maxRow - minRow + 1) * (maxCol - minCol + 1);
109705
+ const expandedIds = new Set(expanded.map((p) => p.cell.id));
109706
+ if (expandedIds.size !== expectedCount) throw new Error("必须是完整矩形");
109575
109707
  for (let row = minRow; row <= maxRow; row++) for (let col = minCol; col <= maxCol; col++) {
109576
109708
  var _table$rows$row;
109577
109709
  const cell = (_table$rows$row = table.rows[row]) === null || _table$rows$row === void 0 ? void 0 : _table$rows$row.cells[col];
109578
- if (!cell || !selectedIds.has(cell.id)) throw new Error("Merge requires a complete rectangle selection");
109579
- if (!cell.mergeId) continue;
109580
- if (mergeRoots.has(cell.mergeId)) continue;
109581
- if (cell.isMergeStart) {
109582
- mergeRoots.set(cell.mergeId, cell);
109583
- continue;
109584
- }
109585
- let root;
109586
- table.forEachCell({
109587
- startRowIdx: 0,
109588
- endRowIdx: table.children.length - 1,
109589
- startColIdx: 0,
109590
- endColIdx: table.rows[0].cells.length - 1,
109591
- filter: (c) => c.id === cell.mergeId,
109592
- callback: (c) => {
109593
- root = c;
109594
- }
109595
- });
109596
- if (root) mergeRoots.set(root.mergeId, root);
109597
- }
109598
- for (const root of mergeRoots.values()) {
109599
- const rRoot = root.parent.getCurrentIndex();
109600
- const cRoot = root.getCurrentIndex();
109601
- const rs = root.rowspan || 1;
109602
- const cs = root.colspan || 1;
109603
- const endRow = rRoot + rs - 1;
109604
- const endCol = cRoot + cs - 1;
109605
- if (rRoot < minRow || endRow > maxRow || cRoot < minCol || endCol > maxCol) throw new Error("Cannot merge: selection partially overlaps an existing merged region");
109710
+ if (!cell || !expandedIds.has(cell.id)) throw new Error("Merge requires a complete rectangle selection");
109606
109711
  }
109607
109712
  },
109608
109713
  mutate: () => {
109609
109714
  var _table$rows$minRow;
109610
109715
  topLeftCell = (_table$rows$minRow = table.rows[minRow]) === null || _table$rows$minRow === void 0 ? void 0 : _table$rows$minRow.cells[minCol];
109611
109716
  if (!topLeftCell) throw new Error("Cannot locate top-left cell for merge");
109612
- topLeftCell.merge(rowSpan, colSpan, { skipConsistency: true });
109717
+ topLeftCell.merge(maxRow - minRow + 1, maxCol - minCol + 1, { skipConsistency: true });
109613
109718
  }
109614
109719
  });
109615
109720
  const mapper = this.doc.layoutMapper;
@@ -123234,20 +123339,19 @@ function findLastIndex(array, predicate) {
123234
123339
  var BomEntryValidator, BomEntriesValidator;
123235
123340
  var init_bom_validator = __esmMin((() => {
123236
123341
  init_service$5();
123237
- init_types$2();
123238
123342
  init_defineProperty();
123239
123343
  BomEntryValidator = class {
123240
123344
  /** 剩于可消耗数量 */
123241
123345
  get remainingNum() {
123242
123346
  return this.total - this.hasConsumed;
123243
123347
  }
123244
- constructor(bomEntry, enableSequenceLoading, materialNoNum, historyData, mainMaterialNo, mcPattern) {
123348
+ constructor(bomEntry, enableSequenceLoading, materialNoNum, historyData, mainMaterialNo, noBomMode) {
123245
123349
  _defineProperty(this, "bomEntry", void 0);
123246
123350
  _defineProperty(this, "enableSequenceLoading", void 0);
123247
123351
  _defineProperty(this, "materialNoNum", void 0);
123248
123352
  _defineProperty(this, "historyData", void 0);
123249
123353
  _defineProperty(this, "mainMaterialNo", void 0);
123250
- _defineProperty(this, "mcPattern", void 0);
123354
+ _defineProperty(this, "noBomMode", void 0);
123251
123355
  _defineProperty(
123252
123356
  this,
123253
123357
  /** 该明细使用到的产品的id集合 */
@@ -123277,7 +123381,7 @@ var init_bom_validator = __esmMin((() => {
123277
123381
  this.materialNoNum = materialNoNum;
123278
123382
  this.historyData = historyData;
123279
123383
  this.mainMaterialNo = mainMaterialNo;
123280
- this.mcPattern = mcPattern;
123384
+ this.noBomMode = noBomMode;
123281
123385
  this.productIds.push(this.bomEntry.product_id_);
123282
123386
  this.productCodes[this.bomEntry.product_id_] = this.bomEntry.product_code_;
123283
123387
  if (this.bomEntry.substitute_material_enabled_ && this.bomEntry.substitute_material_entries_) this.bomEntry.substitute_material_entries_.forEach((i) => {
@@ -123420,21 +123524,21 @@ var init_bom_validator = __esmMin((() => {
123420
123524
  }
123421
123525
  };
123422
123526
  BomEntriesValidator = class {
123423
- constructor(entries, enableSequenceLoading, materialNoNum, historyData, mainMaterialNo, mcPattern) {
123527
+ constructor(entries, enableSequenceLoading, materialNoNum, historyData, mainMaterialNo, noBomMode) {
123424
123528
  _defineProperty(this, "entries", void 0);
123425
123529
  _defineProperty(this, "enableSequenceLoading", void 0);
123426
123530
  _defineProperty(this, "materialNoNum", void 0);
123427
123531
  _defineProperty(this, "historyData", void 0);
123428
123532
  _defineProperty(this, "mainMaterialNo", void 0);
123429
- _defineProperty(this, "mcPattern", void 0);
123533
+ _defineProperty(this, "noBomMode", void 0);
123430
123534
  _defineProperty(this, "bomEntryValidators", void 0);
123431
123535
  this.entries = entries;
123432
123536
  this.enableSequenceLoading = enableSequenceLoading;
123433
123537
  this.materialNoNum = materialNoNum;
123434
123538
  this.historyData = historyData;
123435
123539
  this.mainMaterialNo = mainMaterialNo;
123436
- this.mcPattern = mcPattern;
123437
- this.bomEntryValidators = entries.map((i) => new BomEntryValidator(i, enableSequenceLoading, materialNoNum, historyData, mainMaterialNo, mcPattern));
123540
+ this.noBomMode = noBomMode;
123541
+ this.bomEntryValidators = entries.map((i) => new BomEntryValidator(i, enableSequenceLoading, materialNoNum, historyData, mainMaterialNo, noBomMode));
123438
123542
  }
123439
123543
  /**
123440
123544
  * 翻译物料的code
@@ -123472,7 +123576,7 @@ var init_bom_validator = __esmMin((() => {
123472
123576
  * @param row 单行的数据
123473
123577
  */
123474
123578
  validateInBom(row) {
123475
- if (this.mcPattern === MaterialConsumptionPatternEnum.RECORD) return;
123579
+ if (this.noBomMode) return;
123476
123580
  if (!row.product_id_) throw new Error("物料不能为空");
123477
123581
  if (!this.findUtilByProductId(row.product_id_)) {
123478
123582
  const name = row.product_id__lb_ || "";
@@ -123545,7 +123649,7 @@ var init_bom_validator = __esmMin((() => {
123545
123649
  async validateScanCanInsert(arr) {
123546
123650
  const editRow = arr.find((i) => !i.is_confirmed_);
123547
123651
  if (!editRow) throw new Error("没有正在编辑的行");
123548
- if (this.mcPattern === MaterialConsumptionPatternEnum.RECORD) return;
123652
+ if (this.noBomMode) return;
123549
123653
  this.validateInBom(editRow);
123550
123654
  await this.validateSequenceLoading(editRow, arr);
123551
123655
  this.validateSubstitute(arr);
@@ -123826,6 +123930,9 @@ var init_material_consume_table_controller = __esmMin((() => {
123826
123930
  get mcPattern() {
123827
123931
  return this.tmplBom.material_consumption_pattern_ ?? this.tmplBomController.defaultMCPattern;
123828
123932
  }
123933
+ get isRecordPattern() {
123934
+ return this.mcPattern === MaterialConsumptionPatternEnum.RECORD && !this.tmplBom.personal_bom_enabled_;
123935
+ }
123829
123936
  /**
123830
123937
  * 解析规则配置
123831
123938
  */
@@ -123913,7 +124020,7 @@ var init_material_consume_table_controller = __esmMin((() => {
123913
124020
  this.tmplBom = tmplBom;
123914
124021
  this.initScanRule(this.tmplBom.barcode_parsing_rules_id_);
123915
124022
  markRaw(this);
123916
- this.bomEntriesValidator = new BomEntriesValidator(this.actualBomEntries, this.enableSequenceLoading, this.materialNoNum, this.tmplBomController.historyData, this.tmplBomController.materialNo, this.mcPattern);
124023
+ this.bomEntriesValidator = new BomEntriesValidator(this.actualBomEntries, this.enableSequenceLoading, this.materialNoNum, this.tmplBomController.historyData, this.tmplBomController.materialNo, this.isRecordPattern);
123917
124024
  }
123918
124025
  /** 错误信息 */
123919
124026
  error(message) {
@@ -124003,7 +124110,6 @@ var init_material_consume_table_controller = __esmMin((() => {
124003
124110
  async parseScanStr(str, option) {
124004
124111
  var _this$scanRuleProps;
124005
124112
  if (!this.isFirstBlankRow() && this.hasEditingRow()) return;
124006
- const isRecordPattern = this.mcPattern === MaterialConsumptionPatternEnum.RECORD;
124007
124113
  const data = getParseRuleValue$1(str, this.scanRules);
124008
124114
  console.log("parseScanStr", data);
124009
124115
  const arr = await materialCheck({
@@ -124011,15 +124117,15 @@ var init_material_consume_table_controller = __esmMin((() => {
124011
124117
  production_identification_name_: data.lot,
124012
124118
  qty_: data.qty,
124013
124119
  validate_: data.expiration,
124014
- bom_entries_: isRecordPattern ? null : this.actualBomEntries,
124120
+ bom_entries_: this.isRecordPattern ? null : this.actualBomEntries,
124015
124121
  operation_id_: this.tmplBomController.operationId
124016
- }) || (isRecordPattern ? [{ productionIdentificationName: data.lot }] : null);
124122
+ }) || (this.isRecordPattern ? [{ productionIdentificationName: data.lot }] : null);
124017
124123
  if (!arr) {
124018
124124
  this.error("扫描的物料不存在或不在bom中");
124019
124125
  return;
124020
124126
  }
124021
124127
  let materialData = arr[0];
124022
- if (arr.length > 1 && !isRecordPattern) {
124128
+ if (arr.length > 1 && !this.isRecordPattern) {
124023
124129
  const ids = this.actualTableData.map((i) => i.product_id_);
124024
124130
  const find = arr.find((j) => ids.includes(j.materialId));
124025
124131
  if (!find) throw new Error("表格数据里没有匹配的物料,请选择该物料后再扫码");
@@ -124031,7 +124137,7 @@ var init_material_consume_table_controller = __esmMin((() => {
124031
124137
  qty_: data.qty,
124032
124138
  is_confirmed_: false
124033
124139
  };
124034
- if (isRecordPattern && !row.product_id_) row._scanFallback = true;
124140
+ if (this.isRecordPattern && !row.product_id_) row._scanFallback = true;
124035
124141
  if ((_this$scanRuleProps = this.scanRuleProps) === null || _this$scanRuleProps === void 0 || (_this$scanRuleProps = _this$scanRuleProps.fillMapArr) === null || _this$scanRuleProps === void 0 ? void 0 : _this$scanRuleProps.length) {
124036
124142
  const fillData = calcFillData(data, this.scanRuleProps.fillMapArr);
124037
124143
  console.log("fillData", fillData);
@@ -124116,7 +124222,7 @@ var init_material_consume_table_controller = __esmMin((() => {
124116
124222
  async confirm(option, subModelKey, doc) {
124117
124223
  try {
124118
124224
  if (doc) await this.applyUnitConversionBeforeConfirm(option, doc);
124119
- if (this.mcPattern === MaterialConsumptionPatternEnum.RECORD) {
124225
+ if (this.isRecordPattern) {
124120
124226
  const { dataManager, rowIndex, subFieldKey } = option;
124121
124227
  const row = (dataManager.getRawData()[subFieldKey] ?? [])[rowIndex];
124122
124228
  if (!row) throw new Error("请填写数据");
@@ -124140,7 +124246,7 @@ var init_material_consume_table_controller = __esmMin((() => {
124140
124246
  if (!rules.length) return;
124141
124247
  const rawRows = dataManager.getRawData()[subFieldKey] ?? [];
124142
124248
  const tableRows = ((_this$tableDataRef = this.tableDataRef) === null || _this$tableDataRef === void 0 ? void 0 : _this$tableDataRef.value) ?? rawRows;
124143
- const row = this.mcPattern === MaterialConsumptionPatternEnum.RECORD ? tableRows[rowIndex] ?? rawRows[rowIndex] : tableRows.find((item) => !item.is_confirmed_ && !item.deleted_) ?? rawRows.find((item) => !item.is_confirmed_ && !item.deleted_);
124249
+ const row = this.isRecordPattern ? tableRows[rowIndex] ?? rawRows[rowIndex] : tableRows.find((item) => !item.is_confirmed_ && !item.deleted_) ?? rawRows.find((item) => !item.is_confirmed_ && !item.deleted_);
124144
124250
  if (!row) return;
124145
124251
  if (!await applyUnitConversionRules({
124146
124252
  rules,
@@ -125072,7 +125178,7 @@ async function initializeDocumentEngine(props, payload, result) {
125072
125178
  loadSubModels: true
125073
125179
  });
125074
125180
  const cloneRuntimeJson = cloneDeep(JSON.parse(requestInfo.runtimeJson || "{}"));
125075
- const { runtimeJson: runtimeJsonForModel, infosMap, regions: checkTableRegions } = await prepareCheckTableRuntimeJson(fillModeType === DocModeTypeConst.Edit ? "" : id, cloneRuntimeJson);
125181
+ const { runtimeJson: runtimeJsonForModel, infosMap, regions: checkTableRegions } = await prepareCheckTableRuntimeJson(fillModeType !== DocModeTypeConst.Edit && payload.factoryType === "instance" ? id : "", cloneRuntimeJson);
125076
125182
  const docModel = ModelConverter.toModel(runtimeJsonForModel);
125077
125183
  const templateId = result.tid.split(":")[1];
125078
125184
  await syncMaterialConsumeTableBomInfo(templateId, docModel);
@@ -130347,22 +130453,48 @@ function loadDataUrlAsImage(dataUrl) {
130347
130453
  img.onload = () => resolve(img);
130348
130454
  });
130349
130455
  }
130456
+ function buildSignatureCacheKey(name, width, height, time) {
130457
+ return `${name}\0${width}x${height}\0${time ?? ""}`;
130458
+ }
130459
+ /** 同步取无图签名缓存(布局重建时可避免先闪占位再异步补图) */
130460
+ function getCachedSignatureImage(name, width = 180, height = 102, time) {
130461
+ const w = Math.max(1, Math.round(width));
130462
+ const h = Math.max(1, Math.round(height));
130463
+ return signatureImageCache.get(buildSignatureCacheKey(name, w, h, time)) ?? null;
130464
+ }
130350
130465
  /**
130351
130466
  * 创建无图签名兜底图(用户名 + 电子签名 + 验证日期)
130352
130467
  * 按字段宽高绘制,显示框设多大,字就按多大排
130353
130468
  */
130354
130469
  function createSignatureImageDataUrl(name, width = 180, height = 102, time) {
130355
- return createFormSignFallbackImage(name, Math.max(1, Math.round(width)), Math.max(1, Math.round(height)), time);
130470
+ const w = Math.max(1, Math.round(width));
130471
+ const h = Math.max(1, Math.round(height));
130472
+ const key = buildSignatureCacheKey(name, w, h, time);
130473
+ const cached = signatureDataUrlCache.get(key);
130474
+ if (cached) return cached;
130475
+ const dataUrl = createFormSignFallbackImage(name, w, h, time);
130476
+ signatureDataUrlCache.set(key, dataUrl);
130477
+ return dataUrl;
130356
130478
  }
130357
130479
  function createSignatureImage(name, width = 180, height = 102, time) {
130358
- return loadDataUrlAsImage(createSignatureImageDataUrl(name, width, height, time));
130480
+ const w = Math.max(1, Math.round(width));
130481
+ const h = Math.max(1, Math.round(height));
130482
+ const key = buildSignatureCacheKey(name, w, h, time);
130483
+ const cached = signatureImageCache.get(key);
130484
+ if (cached) return Promise.resolve(cached);
130485
+ return loadDataUrlAsImage(createSignatureImageDataUrl(name, w, h, time)).then((img) => {
130486
+ signatureImageCache.set(key, img);
130487
+ return img;
130488
+ });
130359
130489
  }
130360
- var SIGN_CANVAS_BASE_WIDTH, FALLBACK_SIGN_DPR, ELECTRONIC_SIGNATURE_LABEL, DATE_LABEL;
130490
+ var SIGN_CANVAS_BASE_WIDTH, FALLBACK_SIGN_DPR, ELECTRONIC_SIGNATURE_LABEL, DATE_LABEL, signatureImageCache, signatureDataUrlCache;
130361
130491
  var init_image_size_util = __esmMin((() => {
130362
130492
  SIGN_CANVAS_BASE_WIDTH = 240;
130363
130493
  FALLBACK_SIGN_DPR = 2;
130364
130494
  ELECTRONIC_SIGNATURE_LABEL = "电子签名";
130365
130495
  DATE_LABEL = "日期";
130496
+ signatureImageCache = /* @__PURE__ */ new Map();
130497
+ signatureDataUrlCache = /* @__PURE__ */ new Map();
130366
130498
  }));
130367
130499
  //#endregion
130368
130500
  //#region src/runtime/renderer/dialogs/signature/logic.ts
@@ -144518,9 +144650,24 @@ var gct_signature_render_vue_vue_type_script_setup_true_name_gct_signature_rende
144518
144650
  height: imageHeight.value ?? 102,
144519
144651
  fill: "#f3f3f3"
144520
144652
  }));
144653
+ function applyImage(img) {
144654
+ natural.value = {
144655
+ width: img.naturalWidth,
144656
+ height: img.naturalHeight
144657
+ };
144658
+ display.value = computeContainDisplaySize(natural.value, {
144659
+ width: imageWidth.value,
144660
+ height: imageHeight.value
144661
+ });
144662
+ imgRef.value = img;
144663
+ }
144521
144664
  async function loadImage() {
144522
144665
  const { src, signature, signTime } = props.widget;
144523
- if (signature) return await createSignatureImage(signature, imageWidth.value, imageHeight.value, signTime);
144666
+ if (signature) {
144667
+ const cached = getCachedSignatureImage(signature, imageWidth.value, imageHeight.value, signTime);
144668
+ if (cached) return cached;
144669
+ return await createSignatureImage(signature, imageWidth.value, imageHeight.value, signTime);
144670
+ }
144524
144671
  if (src) return await AssetHelper.loadImage(src);
144525
144672
  return null;
144526
144673
  }
@@ -144531,17 +144678,16 @@ var gct_signature_render_vue_vue_type_script_setup_true_name_gct_signature_rende
144531
144678
  imageWidth.value,
144532
144679
  imageHeight.value
144533
144680
  ], async () => {
144681
+ if (props.widget.signature) {
144682
+ const cached = getCachedSignatureImage(props.widget.signature, imageWidth.value, imageHeight.value, props.widget.signTime);
144683
+ if (cached) {
144684
+ applyImage(cached);
144685
+ return;
144686
+ }
144687
+ }
144534
144688
  const img = await loadImage();
144535
144689
  if (!img) return;
144536
- natural.value = {
144537
- width: img.naturalWidth,
144538
- height: img.naturalHeight
144539
- };
144540
- display.value = computeContainDisplaySize(natural.value, {
144541
- width: imageWidth.value,
144542
- height: imageHeight.value
144543
- });
144544
- imgRef.value = img;
144690
+ applyImage(img);
144545
144691
  }, { immediate: true });
144546
144692
  const imageConfig = computed(() => ({
144547
144693
  x: (imageWidth.value - display.value.width) / 2,
@@ -1,4 +1,4 @@
1
- import { IBomEntry, IMaterialConsumeData, MaterialConsumptionPatternEnum } from '../../../../../domain/table/business/material/types';
1
+ import { IBomEntry, IMaterialConsumeData } from '../../../../../domain/table/business/material/types';
2
2
  export declare class BomEntryValidator {
3
3
  bomEntry: IBomEntry;
4
4
  /** 是否启用顺序投料 */
@@ -10,7 +10,7 @@ export declare class BomEntryValidator {
10
10
  /** 表单实例的批次号 */
11
11
  mainMaterialNo: string;
12
12
  /** 物料消耗模式 */
13
- mcPattern: MaterialConsumptionPatternEnum;
13
+ noBomMode: boolean;
14
14
  /** 该明细使用到的产品的id集合 */
15
15
  productIds: string[];
16
16
  /** 物料和code的映射 */
@@ -31,7 +31,7 @@ export declare class BomEntryValidator {
31
31
  /** 表单实例的批次号 */
32
32
  mainMaterialNo: string,
33
33
  /** 物料消耗模式 */
34
- mcPattern: MaterialConsumptionPatternEnum);
34
+ noBomMode: boolean);
35
35
  /**
36
36
  * 翻译物料的code
37
37
  * @param productId
@@ -90,7 +90,7 @@ export declare class BomEntriesValidator {
90
90
  /** 表单实例的批次号 */
91
91
  mainMaterialNo: string;
92
92
  /** 物料消耗模式 */
93
- mcPattern: MaterialConsumptionPatternEnum;
93
+ noBomMode: boolean;
94
94
  bomEntryValidators: BomEntryValidator[];
95
95
  constructor(entries: IBomEntry[],
96
96
  /** 是否启用顺序投料 */
@@ -102,7 +102,7 @@ export declare class BomEntriesValidator {
102
102
  /** 表单实例的批次号 */
103
103
  mainMaterialNo: string,
104
104
  /** 物料消耗模式 */
105
- mcPattern: MaterialConsumptionPatternEnum);
105
+ noBomMode: boolean);
106
106
  /**
107
107
  * 翻译物料的code
108
108
  * @param productId
@@ -89,6 +89,7 @@ export declare class MaterialConsumeTableController {
89
89
  get materialNoNum(): number;
90
90
  /** 物料消耗模式(自身没有配置的话取环境的默认值) */
91
91
  get mcPattern(): MaterialConsumptionPatternEnum;
92
+ get isRecordPattern(): boolean;
92
93
  /**
93
94
  * 解析规则数据对象
94
95
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gct-paas/word",
3
- "version": "0.1.73-patch.2",
3
+ "version": "0.1.73-patch.4",
4
4
  "description": "GCT 在线 word",
5
5
  "keywords": [
6
6
  "vue",