@gct-paas/excel 0.1.39-beta.43 → 0.1.39-beta.46

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 (63) hide show
  1. package/dist/{BaseComponent-DhTXxc4x.js → BaseComponent-D_qr1qAV.js} +1 -1
  2. package/dist/{barcode-design-NS1lArmz.js → barcode-design-B1E1I0h9.js} +1 -1
  3. package/dist/base/index.es.js +34 -11
  4. package/dist/{diagonal-design-Cwftu7hx.js → diagonal-design-vUC0R6G9.js} +1 -1
  5. package/dist/{dynamic-table-action-prScpPSO.js → dynamic-table-action-BjNAbOiM.js} +69 -47
  6. package/dist/excel.css +72 -58
  7. package/dist/{exceljs.min-C8jXFWc7.js → exceljs.min-ruMnRdmJ.js} +1 -1
  8. package/dist/{font-editor-CsApTDPC.js → font-editor-KgE3aTA7.js} +1 -1
  9. package/dist/{index-BHvLNvGx.js → index-B1Zk4PhS.js} +1 -1
  10. package/dist/{index-BVdJYwE3.js → index-BK2bj0YC.js} +1 -1
  11. package/dist/{index-COddIoq-.js → index-BkrySdbu.js} +2 -2
  12. package/dist/{index-mfqsTXoB.js → index-BtAn5HaV.js} +1 -1
  13. package/dist/{index-CxPjhQyf.js → index-C3GeooR3.js} +1 -1
  14. package/dist/{index-yo02_Auy.js → index-CHFipq2D.js} +1 -1
  15. package/dist/{index-8qbd3NxM.js → index-CKKmoHnx.js} +2 -2
  16. package/dist/{index-D_up7D_j.js → index-CWr2IJif.js} +1 -1
  17. package/dist/{index-k2fPE1RL.js → index-CeUHeApW.js} +1 -1
  18. package/dist/{index-DyMkQIRS.js → index-CpDIChOU.js} +1 -1
  19. package/dist/{index-D9x5f9Aq.js → index-CquK-4J5.js} +1 -1
  20. package/dist/{index-D6wyJoQk.js → index-D0wXTI_4.js} +3 -3
  21. package/dist/{index-D9hguffi.js → index-DC9Ri3CX.js} +355 -181
  22. package/dist/{index-DxlyGiK8.js → index-DPZCDmkK.js} +2 -2
  23. package/dist/{index-D1mJkeww.js → index-DSFStTXw.js} +1 -1
  24. package/dist/{index-0mcNFwv7.js → index-DierjEYd.js} +1 -1
  25. package/dist/{index-CbsfoOi4.js → index-DnmoxMpn.js} +1 -1
  26. package/dist/{index-DK3dd2is.js → index-DoOqRMkR.js} +2 -2
  27. package/dist/{index-DCrPZFf7.js → index-Dojxm4da.js} +2 -2
  28. package/dist/{index-BEIwixHG.js → index-DqeDXZCe.js} +1 -1
  29. package/dist/{index-D-Xv5wzv.js → index-DvzscBgj.js} +1 -1
  30. package/dist/{index-Bjd5wuw-.js → index-DzW9E770.js} +1 -1
  31. package/dist/{index-CKEpTba9.js → index-bBk6szgy.js} +2 -2
  32. package/dist/{index-BH-h7Bat.js → index-owxyHZ4N.js} +1 -1
  33. package/dist/index.es.js +1 -1
  34. package/dist/{pagination-design-DITDQsUU.js → pagination-design-BqD1xNnj.js} +1 -1
  35. package/dist/paper-widget-design-0Wlu4W7D.js +4 -0
  36. package/dist/{print-runtime-instance-CvgieNN9.js → print-runtime-instance-D-zZ-Pnj.js} +1 -1
  37. package/dist/{print-snapshot-renderer-ex82O_4p.js → print-snapshot-renderer-CAu5xiAs.js} +3 -3
  38. package/dist/{qrcode-design-BGpk7DbL.js → qrcode-design-Dx0mGVK1.js} +1 -1
  39. package/dist/seal-design-BSsVnsgS.js +4 -0
  40. package/dist/{single-field-drop-D6uaQgvU.js → single-field-drop-CadWmOmY.js} +1 -1
  41. package/dist/src/nocode-base/src/hooks/material-consume/bom-validator.d.ts +2 -2
  42. package/dist/src/nocode-base/src/hooks/material-consume/material-consume-table-controller.d.ts +14 -13
  43. package/dist/src/nocode-base/src/hooks/material-consume/tmpl-bom-controller.d.ts +8 -0
  44. package/dist/src/online-form/src/views/__cell_widgets__/cell-widget-design.vue.d.ts +1 -0
  45. package/dist/src/online-form/src/views/render/__components__/_field_/trace/composables/useReferenceLabel.d.ts +4 -0
  46. package/dist/{sub-table-factory-BN0oN8fv.js → sub-table-factory-oIHIEDd1.js} +1 -1
  47. package/dist/{text-design-BWOLDnTX.js → text-design-DvaCN4xE.js} +1 -1
  48. package/dist/{trace-like-wrapper-Cpc_zYa_.js → trace-like-wrapper-DjdghEJk.js} +1 -1
  49. package/dist/{value-editor.vue_vue_type_style_index_0_lang-frsVEjsA.js → value-editor.vue_vue_type_style_index_0_lang-DOoBSxtT.js} +1 -1
  50. package/dist/{widget-barcode-EVHu7mED.js → widget-barcode-Bihp8eQf.js} +2 -2
  51. package/dist/{widget-diagonal-Diw_gUHO.js → widget-diagonal-CU143lb2.js} +2 -2
  52. package/dist/{widget-image-Cbtyhn6y.js → widget-image-CvQtHO9u.js} +1 -1
  53. package/dist/{widget-line-DUUUqzV9.js → widget-line-BWWibbG3.js} +1 -1
  54. package/dist/{widget-pagination-BN0-keGV.js → widget-pagination-BOlbp2M6.js} +2 -2
  55. package/dist/{widget-power-Bh_7NHI0.js → widget-power-BQrjZJ0s.js} +2 -2
  56. package/dist/{widget-qrcode-B03rwAGe.js → widget-qrcode-CMrJuNbq.js} +2 -2
  57. package/dist/{widget-rangelimit-BInkWZeQ.js → widget-rangelimit-CGkoloXm.js} +2 -2
  58. package/dist/{widget-serialnumber-BaL2uasA.js → widget-serialnumber-Rwq-qlyD.js} +1 -1
  59. package/dist/{widget-text-C0Y_wCd_.js → widget-text-Qj9jHnAY.js} +3 -3
  60. package/dist/{widget-timediff-vo-vEV1L.js → widget-timediff-DVtLFiEW.js} +1 -1
  61. package/package.json +1 -1
  62. package/dist/paper-widget-design-BGs8VQMz.js +0 -4
  63. package/dist/seal-design-BTVRnLdn.js +0 -4
@@ -1,4 +1,4 @@
1
- import { h as normalizeFieldWidth } from "./dynamic-table-action-prScpPSO.js";
1
+ import { h as normalizeFieldWidth } from "./dynamic-table-action-BjNAbOiM.js";
2
2
  import { get, pick } from "lodash-es";
3
3
  import { F as FIELD_TYPE } from "./dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-anSsEnF9.js";
4
4
  import { f as fontStyleAttrs } from "./config.enum-B8UZQTON.js";
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, ref, computed, watch, openBlock, createElementBlock, normalizeStyle, normalizeClass, createElementVNode, toDisplayString, createCommentVNode } from "vue";
2
2
  import { pick } from "lodash-es";
3
- import { u as useSpreadSheet, h as useModelFields, l as loadBwip } from "./index-D9hguffi.js";
3
+ import { u as useSpreadSheet, h as useModelFields, l as loadBwip } from "./index-DC9Ri3CX.js";
4
4
  import { Q as PaperWidgeValueType, a7 as _export_sfc } from "./dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-anSsEnF9.js";
5
5
  import "dayjs";
6
6
  import "ant-design-vue";
@@ -1,12 +1,12 @@
1
1
  import { E as api, _ as PlatformEnum, F as FIELD_TYPE, bc as getRowId, bd as findRuntimeTableRow, b5 as RenderModeEnum, C as ComponentTypeEnum, aF as Dependency_ENUM, aE as ASSIGNMENTSTRATEGY_ENUM, bn as fetchHistoryConsume, bo as isBomGranted, aT as renderUtils, bm as uuid2, bp as parseFrontConfig, aI as CheckDsTypeEnum, aC as transformUtils, bq as baseDataUtils, X as FormTypeEnum, br as normalizeToArray, bs as safeParseArray, bt as BpmnNodeTypeEnum, bu as mergeByMultiKey, a7 as _export_sfc, bv as evaluateInspectionDecisionRule, bw as useNocodeEmitter, bx as commonUtils, aG as EntityModelCategoryEnum } from "../dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-anSsEnF9.js";
2
2
  import { aL, aN, a_, a0, by, bz, B, bA, y, af, bB, bC, bD, bb, bE, aQ, av, aM, aJ, aK, bF, ag, ak, bG, bH, aD, a2, ae, aw, aO, $, ai, L, bI, bJ, bK, O, p, P, a9, o, Q, A, bL, bM, au, at, a5, a1, a3, a4, a6, f, bN, aj, an, ah, bO, bP, bQ, bR, ba, bS, bT, bU, bV, bW, bX, bY, bZ, b_, b$, be, c0, c1, aW, c2, a$, b0, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, aV, cd, b1, b8, ce, cf, al, t, aP, cg, ch, bf, aX } from "../dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-anSsEnF9.js";
3
- import { a2 as getRuntimeDataFieldId, O as parseRuntimeFieldPath, a3 as buildRuntimeFieldPath, a4 as resolveRuntimeFieldProps, a5 as resolveRuntimeFieldState, a6 as assembleRules, a7 as isAttachFieldActive, P as calculateFormula, a8 as getRuntimeDependencyOutputKey, a9 as isRowAddedInCurrentFormChange, c as getParseFormulaVarInfos, w as MaterialConsumptionPatternEnum, aa as MaterialConsumeTableController, ab as setFormulaParamsConfig, ac as normalizeRuntime, V as createRuntimeInstanceContext, ad as initializeSealFields, U as RuntimeFormStateStore, ae as RuntimeSheetService, g as getBusinessFieldKey, af as validateObjectBomQtyOnSubmit, ag as areValidationCommentsEqual, ah as closeValidatorPopovers, ai as enrichFormChangeRowDetails, N as NCB_PROVIDE, W as RuntimeInstanceRegistry, aj as useMaterialBalance, ak as collectFormChangeFieldLocations, al as nextFormChangeRowViewHistoryId } from "../dynamic-table-action-prScpPSO.js";
4
- import { B as B2, am, k, a1 as a12, an as an2, $ as $2, ao, a0 as a02, F, ap, aq, ar, as, at as at2, M, a, au as au2, b, av as av2, aw as aw2, ax, ay, az, aA, aB, aC, C, aD as aD2, t as t2, aE, d, aF, aG, aH, aI, r, E, aJ as aJ2, aK as aK2, aL as aL2, aM as aM2, l, G, j, aN as aN2, aO as aO2, aP as aP2, aQ as aQ2, aR, aS, aT, y as y2, v, aU, z, p as p2, aV as aV2, s, aW as aW2, R, S, u, A as A2, T, o as o2, q, Q as Q2, m, x } from "../dynamic-table-action-prScpPSO.js";
3
+ import { a2 as getRuntimeDataFieldId, O as parseRuntimeFieldPath, a3 as buildRuntimeFieldPath, a4 as resolveRuntimeFieldProps, a5 as resolveRuntimeFieldState, a6 as assembleRules, a7 as isAttachFieldActive, P as calculateFormula, a8 as getRuntimeDependencyOutputKey, a9 as isRowAddedInCurrentFormChange, c as getParseFormulaVarInfos, w as MaterialConsumptionPatternEnum, aa as MaterialConsumeTableController, ab as setFormulaParamsConfig, ac as normalizeRuntime, V as createRuntimeInstanceContext, ad as initializeSealFields, U as RuntimeFormStateStore, ae as RuntimeSheetService, g as getBusinessFieldKey, af as validateObjectBomQtyOnSubmit, ag as areValidationCommentsEqual, ah as closeValidatorPopovers, ai as enrichFormChangeRowDetails, N as NCB_PROVIDE, W as RuntimeInstanceRegistry, aj as useMaterialBalance, ak as collectFormChangeFieldLocations, al as nextFormChangeRowViewHistoryId } from "../dynamic-table-action-BjNAbOiM.js";
4
+ import { B as B2, am, k, a1 as a12, an as an2, $ as $2, ao, a0 as a02, F, ap, aq, ar, as, at as at2, M, a, au as au2, b, av as av2, aw as aw2, ax, ay, az, aA, aB, aC, C, aD as aD2, t as t2, aE, d, aF, aG, aH, aI, r, E, aJ as aJ2, aK as aK2, aL as aL2, aM as aM2, l, G, j, aN as aN2, aO as aO2, aP as aP2, aQ as aQ2, aR, aS, aT, y as y2, v, aU, z, p as p2, aV as aV2, s, aW as aW2, R, S, u, A as A2, T, o as o2, q, Q as Q2, m, x } from "../dynamic-table-action-BjNAbOiM.js";
5
5
  import { toRaw, watch, toRef, computed, defineComponent, openBlock, createElementBlock, createElementVNode, toDisplayString, ref, provide, onUnmounted, markRaw, reactive, onBeforeUnmount } from "vue";
6
6
  import { cloneDeep, defaults, isEmpty, merge } from "lodash-es";
7
7
  import "dayjs";
8
- import { S as SubTableCoreFactory, R as RuntimeInstanceController } from "../sub-table-factory-BN0oN8fv.js";
9
- import { A as A3, D, M as M2, a as a7, P as P2, b as b2, c, d as d2, e, W, f as f2, g, h } from "../sub-table-factory-BN0oN8fv.js";
8
+ import { S as SubTableCoreFactory, R as RuntimeInstanceController } from "../sub-table-factory-oIHIEDd1.js";
9
+ import { A as A3, D, M as M2, a as a7, P as P2, b as b2, c, d as d2, e, W, f as f2, g, h } from "../sub-table-factory-oIHIEDd1.js";
10
10
  import { B as B3, F as F2, M as M3, a as a8, u as u2 } from "../mb-render-BjNRjLdf.js";
11
11
  const InstanceStatusValues = {
12
12
  /** 作废状态 */
@@ -987,6 +987,28 @@ class FormTmplBomController {
987
987
  });
988
988
  });
989
989
  }
990
+ /** 全部 Sheet 的消耗表统一在 LOADED 前准备。 */
991
+ initializeFormState(opts) {
992
+ Object.entries(this.field2TableMap).forEach(([field, tableKey]) => {
993
+ const controller = this.tableControllers[tableKey];
994
+ if (!controller) return;
995
+ controller.prepareInitialData({
996
+ formState: opts.formState,
997
+ field,
998
+ dataStatus: opts.dataStatus,
999
+ defaultRowData: renderUtils.getDefaultValueInfo({
1000
+ defaultDataMap: opts.defaultDataMap,
1001
+ key: field
1002
+ })
1003
+ });
1004
+ });
1005
+ }
1006
+ /** 钩子若修改数量依赖,在创建 Store 和分页前按原规则重算。 */
1007
+ finalizeInitialQuantities() {
1008
+ Object.values(this.tableControllers).forEach((controller) => {
1009
+ controller.syncQtyRequiredFromBomIfChanged();
1010
+ });
1011
+ }
990
1012
  async submitValidate() {
991
1013
  const results = await Promise.all(
992
1014
  Object.values(this.tableControllers).map((c10) => c10.submitValidate())
@@ -1541,6 +1563,11 @@ function createRuntimeInstanceInitializer(props, payload, getConsumeData) {
1541
1563
  });
1542
1564
  initializeSealFields(floatingFields, formState);
1543
1565
  }
1566
+ tmplBomC.initializeFormState({
1567
+ formState,
1568
+ dataStatus: selfInfo.dataStatus,
1569
+ defaultDataMap
1570
+ });
1544
1571
  await transformUtils.getEventInitDataLoaded({
1545
1572
  formConfig: runtimeContext.formConfig,
1546
1573
  formState,
@@ -1550,6 +1577,7 @@ function createRuntimeInstanceInitializer(props, payload, getConsumeData) {
1550
1577
  }).catch((error) => {
1551
1578
  console.error("Error in getEventInitDataLoaded:", error);
1552
1579
  });
1580
+ tmplBomC.finalizeInitialQuantities();
1553
1581
  runtimeFormStateStore = new RuntimeFormStateStore(
1554
1582
  formState,
1555
1583
  // 子表信息覆盖普通/固定/检验表、二维关联列以及各类业务表;不能只依赖已放置字段。
@@ -1697,18 +1725,13 @@ function bindRuntimeBusinessServices(runtimeRegistry, record, dataStatus) {
1697
1725
  }
1698
1726
  }),
1699
1727
  mainFormState: computed(() => record.formState.state),
1700
- dataStatus,
1701
- defaultRowData: renderUtils.getDefaultValueInfo({
1702
- defaultDataMap: record.context.defaultData,
1703
- key: field
1704
- })
1728
+ dataStatus
1705
1729
  });
1706
1730
  stops.push(
1707
1731
  watch(
1708
1732
  () => controller.materialNoNum,
1709
1733
  () => {
1710
- if (controller.dataStatus === "SUBMIT") return;
1711
- controller.syncQtyRequiredFromBom();
1734
+ controller.syncQtyRequiredFromBomIfChanged();
1712
1735
  },
1713
1736
  { immediate: true }
1714
1737
  )
@@ -1,5 +1,5 @@
1
1
  import { defineComponent, computed, openBlock, createBlock } from "vue";
2
- import { h as useModelFields, D as Diagonal } from "./index-D9hguffi.js";
2
+ import { h as useModelFields, D as Diagonal } from "./index-DC9Ri3CX.js";
3
3
  import { al as resolveDiagonalVertex, a7 as _export_sfc } from "./dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-anSsEnF9.js";
4
4
  import "lodash-es";
5
5
  import "dayjs";
@@ -1,4 +1,4 @@
1
- import { reactive, toRaw, computed, watch, onScopeDispose, inject, h, shallowReactive, markRaw, ref, nextTick, toRef, provide, defineComponent, openBlock, createElementBlock, mergeProps, unref, createElementVNode, normalizeClass, renderSlot, createCommentVNode, createVNode, toDisplayString, Fragment, renderList, onUnmounted, isVNode, onMounted, onBeforeMount, resolveComponent, createBlock, withCtx, createTextVNode } from "vue";
1
+ import { reactive, toRaw, computed, watch, onScopeDispose, inject, h, shallowReactive, markRaw, ref, toRef, nextTick, provide, defineComponent, openBlock, createElementBlock, mergeProps, unref, createElementVNode, normalizeClass, renderSlot, createCommentVNode, createVNode, toDisplayString, Fragment, renderList, onUnmounted, isVNode, onMounted, onBeforeMount, resolveComponent, createBlock, withCtx, createTextVNode } from "vue";
2
2
  import { af as CellWidgetViewState, F as FIELD_TYPE, b5 as RenderModeEnum, X as FormTypeEnum, bt as BpmnNodeTypeEnum, ci as getFieldPlaceholder, bJ as MobileFillTypeEnum, C as ComponentTypeEnum, bd as findRuntimeTableRow, aT as renderUtils, _ as PlatformEnum, E as api, bm as uuid2, bT as calcUtils, bX as ensureTableRowKeys, bQ as bindRuntimeTableColumns, bc as getRowId, cj as FRONT_ROW_KEY, ca as isTableRowKeyMatch, au as RangeCompareOp, at as RangeValidateMode, bU as decodeTableCellRowKey, bW as ensureFrontRowKey, a$ as getParseRuleInfo, aC as transformUtils, aV as materialCheck, aW as getLotLockedReason, aX as validateReinspectionDate, bg as FormulaRuleFieldKeyEnum, f as SubTableType, b0 as getParseRuleValue, H as CreateType, be as findRuntimeParentRow, aF as Dependency_ENUM, aE as ASSIGNMENTSTRATEGY_ENUM, bx as commonUtils, aJ as DeviceLink, a7 as _export_sfc, c4 as getRenderedRuntimeTableCell, y as CellType, ck as resetTableRowIdentity, J as useModal, cl as q, cm as QUICK_FILL_ALLOWED_FIELDS, cn as groupFixedTableRows, co as processQuickFillRows, cp as getIsGroupEmpty } from "./dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-anSsEnF9.js";
3
3
  import dayjs from "dayjs";
4
4
  import { cloneDeep, isEmpty, isNil, pickBy, mergeWith, omit, last, pick, merge } from "lodash-es";
@@ -146,7 +146,8 @@ class RuntimeDependencyService {
146
146
  }
147
147
  schedule(change) {
148
148
  if (this.disposed) return;
149
- if (change.source === "restore") change = { ...change, paths: ["*"] };
149
+ const labelsOnly = change.paths.length > 0 && change.paths.every((path) => path.endsWith("_lb_"));
150
+ if (change.source === "restore" && !labelsOnly) change = { ...change, paths: ["*"] };
150
151
  this.effects.forEach((effect) => {
151
152
  if (this.matches(effect, change.paths)) this.cancelExecution(effect.id);
152
153
  });
@@ -1487,6 +1488,7 @@ class RuntimeFormStateStore {
1487
1488
  constructor(initialState, subtableFields = [], tableRelations = []) {
1488
1489
  this.tableRelations = tableRelations;
1489
1490
  this.subtableFields = new Set(subtableFields);
1491
+ normalizeEmptyReferenceLabels(initialState);
1490
1492
  this.subtableFields.forEach((field) => ensureTableRowKeys(initialState[field]));
1491
1493
  bindRuntimeTableColumns(initialState, this.tableRelations);
1492
1494
  this.reactiveState = reactive(initialState);
@@ -1643,7 +1645,7 @@ class RuntimeFormStateStore {
1643
1645
  this.ensureIncomingRowKeys(target, fieldKey, value);
1644
1646
  const valueChanged = !Object.is(toRaw(this.unwrap(target[fieldKey])), toRaw(value));
1645
1647
  const labelKey = `${fieldKey}_lb_`;
1646
- const clearLabel = (value == null || value === "" || Array.isArray(value) && value.length === 0) && target[labelKey] != null;
1648
+ const clearLabel = isEmptyReferenceValue(value) && target[labelKey] != null;
1647
1649
  if (!valueChanged && !clearLabel) return;
1648
1650
  const paths = valueChanged ? [path] : [];
1649
1651
  if (clearLabel) paths.push(`${path}_lb_`);
@@ -1682,6 +1684,7 @@ class RuntimeFormStateStore {
1682
1684
  this.mutate(Array.from(paths), source, () => {
1683
1685
  Object.keys(this.reactiveState).forEach((key) => delete this.reactiveState[key]);
1684
1686
  this.assignValues(this.reactiveState, values);
1687
+ normalizeEmptyReferenceLabels(this.reactiveState);
1685
1688
  });
1686
1689
  this.userModifiedPaths.clear();
1687
1690
  if (source === "restore") this.dirty = false;
@@ -1862,6 +1865,23 @@ const ARRAY_MUTATIONS = /* @__PURE__ */ new Set([
1862
1865
  "unshift"
1863
1866
  ]);
1864
1867
  const ARRAY_SEARCHES = /* @__PURE__ */ new Set(["includes", "indexOf", "lastIndexOf"]);
1868
+ function isEmptyReferenceValue(value) {
1869
+ return value == null || value === "" || Array.isArray(value) && value.length === 0;
1870
+ }
1871
+ function normalizeEmptyReferenceLabels(value, visited = /* @__PURE__ */ new WeakSet()) {
1872
+ if (!isMutableRecord(value) || visited.has(toRaw(value))) return;
1873
+ visited.add(toRaw(value));
1874
+ Object.entries(value).forEach(([key, child]) => {
1875
+ if (key.endsWith("_lb_")) {
1876
+ const fieldKey = key.slice(0, -4);
1877
+ if (child != null && Object.prototype.hasOwnProperty.call(value, fieldKey) && isEmptyReferenceValue(value[fieldKey])) {
1878
+ value[key] = null;
1879
+ }
1880
+ } else if (key !== "_DICT") {
1881
+ normalizeEmptyReferenceLabels(child, visited);
1882
+ }
1883
+ });
1884
+ }
1865
1885
  function joinPath(basePath, key) {
1866
1886
  return basePath ? `${basePath}.${key}` : key;
1867
1887
  }
@@ -4738,7 +4758,7 @@ class BomEntryValidator {
4738
4758
  }
4739
4759
  /** 需求总量 = 数量倍数 × BOM 单位用量 */
4740
4760
  get total() {
4741
- return this.materialNoNum * this.bomEntry.qty_required_;
4761
+ return this.materialNoNum * Number(this.bomEntry.qty_required_);
4742
4762
  }
4743
4763
  /**
4744
4764
  * 翻译物料的code
@@ -4892,12 +4912,12 @@ class BomEntryValidator {
4892
4912
  */
4893
4913
  calcQtyConsumed(arr = this.historyData) {
4894
4914
  const groupData = this.filterGroupData(arr);
4895
- return groupData.reduce((acc, cur) => acc + (cur.qty_ ?? 0), 0);
4915
+ return groupData.reduce((acc, cur) => acc + Number(cur.qty_ ?? 0), 0);
4896
4916
  }
4897
4917
  /** 上下限校验统一按需求单位口径取转换数量,历史数据未转换时兼容原数量。 */
4898
4918
  calcQtyForBounds(arr) {
4899
4919
  const groupData = this.filterGroupData(arr);
4900
- return groupData.reduce((acc, cur) => acc + (cur.qty_transfer_ ?? cur.qty_ ?? 0), 0);
4920
+ return groupData.reduce((acc, cur) => acc + Number(cur.qty_transfer_ ?? cur.qty_ ?? 0), 0);
4901
4921
  }
4902
4922
  /**
4903
4923
  * 计算自定义的数量校验的最大值和最小值
@@ -4912,9 +4932,10 @@ class BomEntryValidator {
4912
4932
  try {
4913
4933
  const json = JSON.parse(str);
4914
4934
  if (json.expr) {
4915
- return await window.gct_expression.execute(json.expr, {
4916
- qty_required_: data.qty_required_
4935
+ const value = await window.gct_expression.execute(json.expr, {
4936
+ qty_required_: data.qty_required_ == null ? data.qty_required_ : Number(data.qty_required_)
4917
4937
  });
4938
+ return value == null ? void 0 : Number(value);
4918
4939
  } else {
4919
4940
  console.warn("没有配置表达式");
4920
4941
  }
@@ -4941,8 +4962,8 @@ class BomEntryValidator {
4941
4962
  const loaded = this.calcQtyConsumed(arr);
4942
4963
  let required4 = this.remainingNum;
4943
4964
  if (this.isCustomRequiredQty) {
4944
- const currentQty = groupData[0]?.qty_required_;
4945
- if (typeof currentQty !== "number" || !Number.isFinite(currentQty) || currentQty <= 0) {
4965
+ const currentQty = Number(groupData[0]?.qty_required_);
4966
+ if (!Number.isFinite(currentQty) || currentQty <= 0) {
4946
4967
  throw new Error(
4947
4968
  groupNo != null && groupNo > 0 ? `序号${groupNo},需求数量必须大于 0` : "需求数量必须大于 0"
4948
4969
  );
@@ -5756,7 +5777,7 @@ function calcGroupRowSpans(rows, validator) {
5756
5777
  function calcGroupQtyConsumedTotal(entryIdx, tableData, validator) {
5757
5778
  if (entryIdx < 0) return 0;
5758
5779
  return tableData.reduce((sum, row) => {
5759
- return validator.resolveEntryIndex(row) === entryIdx ? sum + (row.qty_ ?? 0) : sum;
5780
+ return validator.resolveEntryIndex(row) === entryIdx ? sum + Number(row.qty_ ?? 0) : sum;
5760
5781
  }, 0);
5761
5782
  }
5762
5783
  function syncGroupQtyConsumedTotals(tableData, validator) {
@@ -5855,8 +5876,10 @@ class MaterialConsumeTableController {
5855
5876
  mainFormState = ref({});
5856
5877
  /** 表单数据状态(由 factory bindRuntime 注入):未填报 / STASH / SUBMIT */
5857
5878
  dataStatus;
5858
- /** factory 是否已绑定过运行时(避免重复 initTableData) */
5859
- runtimeBound = false;
5879
+ /** 实例数据只在 LOADED 前准备一次,运行时绑定不再重新生成行。 */
5880
+ initialDataPrepared = false;
5881
+ /** 最近一次同步需求数量时使用的数量依赖。 */
5882
+ syncedMaterialNoNum;
5860
5883
  /** 多 Sheet / 同屏多实例下,弹层和异步交互使用该键隔离。 */
5861
5884
  runtimeOwnerId = "";
5862
5885
  /** 表单是否已暂存或提交(已处理过则不再跑初始化) */
@@ -6007,7 +6030,7 @@ class MaterialConsumeTableController {
6007
6030
  return this.actualBomEntries.map((i) => {
6008
6031
  return {
6009
6032
  product_id_: i.product_id_,
6010
- ...materialNoNum === void 0 ? {} : { qty_required_: i.qty_required_ * materialNoNum },
6033
+ ...materialNoNum === void 0 ? {} : { qty_required_: Number(i.qty_required_) * Number(materialNoNum) },
6011
6034
  bom_entry_id_: i.id_
6012
6035
  };
6013
6036
  });
@@ -6247,40 +6270,36 @@ class MaterialConsumeTableController {
6247
6270
  });
6248
6271
  this.isScanOpen = false;
6249
6272
  }
6250
- /**
6251
- * 打开扫描弹窗
6252
- * @param opts
6253
- */
6254
- async openBomModal() {
6255
- if (!this.actualBomEntries) {
6256
- return;
6273
+ /** Store 创建前准备物料行和数量,全部 Sheet 的 LOADED 共用这份数据。 */
6274
+ prepareInitialData(opts) {
6275
+ if (this.initialDataPrepared) return;
6276
+ this.tableDataRef = toRef(opts.formState, opts.field, []);
6277
+ this.mainFormState = toRef(() => opts.formState);
6278
+ this.dataStatus = opts.dataStatus;
6279
+ this.initTableData(opts.defaultRowData);
6280
+ const rows = this.actualTableData;
6281
+ if (rows.length === 1 && !rows[0].product_id_) {
6282
+ MCDataUtil.setRowEditing(rows[0], true);
6257
6283
  }
6258
- await MaterialConsumeTableController.render?.openBomModal({
6259
- ownerId: this.runtimeOwnerId,
6260
- bomList: this.actualBomEntries,
6261
- onSubstitute: async () => {
6262
- console.log("一键导入数据逻辑");
6263
- }
6264
- });
6284
+ if (this.dataStatus !== "SUBMIT") {
6285
+ this.syncQtyRequiredFromBom();
6286
+ }
6287
+ this.syncedMaterialNoNum = this.materialNoNum;
6288
+ this.initialDataPrepared = true;
6265
6289
  }
6266
- /**
6267
- * 表单加载时由 factory 调用:绑定稳定数据源并初始化行数据。
6268
- * 不在分页组件 setup 中调用,避免跨页挂载重复 init。
6269
- */
6290
+ /** 数量依赖实际变化时才重算,避免首次绑定覆盖 LOADED 中的回填。 */
6291
+ syncQtyRequiredFromBomIfChanged() {
6292
+ if (this.dataStatus === "SUBMIT") return;
6293
+ const materialNoNum = this.materialNoNum;
6294
+ if (this.initialDataPrepared && Object.is(materialNoNum, this.syncedMaterialNoNum)) return;
6295
+ this.syncQtyRequiredFromBom();
6296
+ this.syncedMaterialNoNum = materialNoNum;
6297
+ }
6298
+ /** 只绑定运行时 Store,不重新生成行或修改行内容。 */
6270
6299
  bindRuntime(opts) {
6271
6300
  this.tableDataRef = opts.tableDataRef;
6272
- this.runtimeOwnerId = opts.ownerId;
6273
6301
  this.mainFormState = opts.mainFormState ?? ref({});
6274
6302
  this.dataStatus = opts.dataStatus;
6275
- if (this.runtimeBound) return;
6276
- this.runtimeBound = true;
6277
- this.initTableData(opts.defaultRowData);
6278
- if (this.actualTableData.length === 1) {
6279
- const firstRow = this.actualTableData[0];
6280
- if (!firstRow.product_id_) {
6281
- MCDataUtil.setRowEditing(firstRow, true);
6282
- }
6283
- }
6284
6303
  }
6285
6304
  /**
6286
6305
  * 消耗表组件挂载时调用:只同步视图依赖,不初始化数据、不注册 watch。
@@ -6294,7 +6313,10 @@ class MaterialConsumeTableController {
6294
6313
  * 按当前 materialNoNum 回写各行 qty_required_(校验侧 total 已通过 getter 实时读取)
6295
6314
  */
6296
6315
  syncQtyRequiredFromBom() {
6297
- if (this.tmplBom.required_qty_calc_rule_ === RequiredQtyCalcRule.Custom) return;
6316
+ if (this.tmplBom.required_qty_calc_rule_ === RequiredQtyCalcRule.Custom) {
6317
+ this.updateDerivedQtyFields();
6318
+ return;
6319
+ }
6298
6320
  this.actualTableData.forEach((row) => {
6299
6321
  if (!row.product_id_) return;
6300
6322
  const util = this.bomEntriesValidator.findUtilByProductId(row.product_id_);
@@ -6338,7 +6360,7 @@ class MaterialConsumeTableController {
6338
6360
  const formData = transformFields.reduce((acc, cur) => {
6339
6361
  if (!cur.targetField) return acc;
6340
6362
  if (cur.sourceField === FormulaRuleFieldKeyEnum.INPUT) {
6341
- acc[cur.sourceField] = row.qty_;
6363
+ acc[cur.sourceField] = row.qty_ == null ? row.qty_ : Number(row.qty_);
6342
6364
  } else if (cur.targetField.includes(".")) {
6343
6365
  const fieldKey = cur.targetField.split(".").pop();
6344
6366
  acc[cur.sourceField] = row[fieldKey];
@@ -6350,7 +6372,7 @@ class MaterialConsumeTableController {
6350
6372
  try {
6351
6373
  const res = await calculate(formulaContent, formData);
6352
6374
  Object.assign(row, {
6353
- qty_transfer_: res,
6375
+ qty_transfer_: res == null ? res : Number(res),
6354
6376
  qty_transfer_uom_id_: targetUnitId,
6355
6377
  transfer_formula_: formulaContent
6356
6378
  });
@@ -6534,7 +6556,7 @@ class MaterialConsumeTableController {
6534
6556
  const modifySingleRow = (index) => {
6535
6557
  const row = this.actualTableData[index];
6536
6558
  if (!row.product_id_) {
6537
- row.qty_consumed_ = 0 + (row.qty_ ?? 0);
6559
+ row.qty_consumed_ = Number(row.qty_ ?? 0);
6538
6560
  return;
6539
6561
  }
6540
6562
  let total = 0;
@@ -6543,7 +6565,7 @@ class MaterialConsumeTableController {
6543
6565
  if (util) {
6544
6566
  total += util.hasConsumed;
6545
6567
  util.filterGroupData(beforeArr).forEach((i) => {
6546
- total += i.qty_ ?? 0;
6568
+ total += Number(i.qty_ ?? 0);
6547
6569
  });
6548
6570
  row.qty_consumed_ = total;
6549
6571
  }