@gct-paas/excel 0.1.40-beta.8 → 0.1.40

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 (170) hide show
  1. package/dist/{BaseComponent-CELRDc47.js → BaseComponent-CD_dAL9D.js} +3 -4
  2. package/dist/{VueVideoPlayer-CQ3WMohj.js → VueVideoPlayer-DQQlv_cp.js} +2 -2
  3. package/dist/{align-editor-BjxHuSxl.js → align-editor-DchzBHaC.js} +1 -1
  4. package/dist/{barcode-design-BDHtEF3j.js → barcode-design-BBW5cG3v.js} +2 -3
  5. package/dist/base/index.es.js +306 -465
  6. package/dist/{diagonal-design-DLxRO_uM.js → diagonal-design-CawGqmc7.js} +2 -3
  7. package/dist/{dynamic-table-action-C_1EGXMe.js → dynamic-table-action-Dw7AIthU.js} +942 -315
  8. package/dist/{dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-B7k5famp.js → dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-DEjLEs33.js} +1246 -1840
  9. package/dist/{edit.utils-CXmmCnxE-C1w2rhHM.js → edit.utils-CXmmCnxE-B7lpVZjb.js} +1 -1
  10. package/dist/excel.css +4642 -3566
  11. package/dist/{exceljs.min-rIUD8u2M.js → exceljs.min-DDPQIUli.js} +2 -2
  12. package/dist/{font-editor-DWmzS_0C.js → font-editor-n8zk8Vt2.js} +3 -3
  13. package/dist/{image-design-Cjob0qMO.js → image-design-D4mIDz9K.js} +2 -2
  14. package/dist/{index--kolAY9o.js → index--MetH_r4.js} +3 -4
  15. package/dist/{index-DJj0H4QE.js → index-1klMDz7G.js} +2 -3
  16. package/dist/{index-B9a9T8if.js → index-4p1VXlOx.js} +1 -2
  17. package/dist/{index-DQNLZ671.js → index-B0u6FHDq.js} +6 -6
  18. package/dist/{index-BeYN1fxt.js → index-BMsHMGap.js} +2 -3
  19. package/dist/{index-nGGsFW_9.js → index-BW95iBc7.js} +2 -3
  20. package/dist/{index-BHxDpc-C.js → index-BWoOPv6-.js} +2 -3
  21. package/dist/{index-CIkhaEj4.js → index-BZ7bC20P.js} +1 -2
  22. package/dist/{index-CQkWk_7M.js → index-BcHwRIXW.js} +3 -4
  23. package/dist/{index-ByeVrxVl.js → index-Bm8wYtHB.js} +1 -2
  24. package/dist/{index-DiNxihKr.js → index-Boy8--Ns.js} +2 -3
  25. package/dist/{index-CQ0BwWRP.js → index-C-NpFAft.js} +3 -3
  26. package/dist/{index-CfyXGhk3.js → index-C4t8sSlN.js} +1 -2
  27. package/dist/{index-RV5ozdPP.js → index-CAc9drK5.js} +1 -2
  28. package/dist/{index-BzBMhjxB.js → index-CI6Hl1Ns.js} +1 -2
  29. package/dist/{index-BlLeFC1A.js → index-CXnuud67.js} +2 -3
  30. package/dist/{index-DdxuhIJY.js → index-CYSJt1Zc.js} +2 -3
  31. package/dist/{index-C-F1u_o7.js → index-Ch88zDje.js} +2 -3
  32. package/dist/{index-CAekmaIN.js → index-CmjTSiUa.js} +2 -3
  33. package/dist/{index-Refavqkv.js → index-DPf5_q0T.js} +5 -5
  34. package/dist/{index-Bn5H-iFV.js → index-DUztXGMj.js} +2 -3
  35. package/dist/{index-poil0x4K.js → index-DfFakGrF.js} +2 -3
  36. package/dist/{index-Bw67kX4Y.js → index-DgybKcgI.js} +2 -3
  37. package/dist/{index-DqomTxsG.js → index-Dh0_kanw.js} +1 -2
  38. package/dist/{index-2X2QGo0A.js → index-DiPWQwMU.js} +29436 -27193
  39. package/dist/{index-CHS101Sz.js → index-DiWzNeZJ.js} +6 -4
  40. package/dist/{index-U90xa0_k.js → index-Do-QyvWW.js} +2 -3
  41. package/dist/{index-Cn2_Yd7q.js → index-DvMu7-8y.js} +1 -2
  42. package/dist/{index-DxaR4DCk.js → index-H4f-e99t.js} +2 -3
  43. package/dist/{index-DMOi4nAC.js → index-S8Dj5ycu.js} +2 -3
  44. package/dist/{index-DxW-5l6p.js → index-TZy8JxSW.js} +5 -8
  45. package/dist/{index-BLpDtBBv.js → index-_Ec5LAW9.js} +2 -2
  46. package/dist/{index-w6agN1-G.js → index-gHOlYnAA.js} +1 -2
  47. package/dist/{index-LOpDQbHn.js → index-r0yHBje3.js} +2 -3
  48. package/dist/{index-BgsXETEd.js → index-r9t3crs-.js} +1 -2
  49. package/dist/index.es.js +10 -14
  50. package/dist/{mb-render-wAlqnYW9.js → mb-render-sgVmAe6_.js} +1 -1
  51. package/dist/{online-form-model-select.vue_vue_type_script_setup_true_name_online-form-model-select_lang-BLEHWjXh.js → online-form-model-select.vue_vue_type_script_setup_true_name_online-form-model-select_lang-DDJetWQU.js} +1 -2
  52. package/dist/{pagination-design-CuM2_cOO.js → pagination-design-lckCQWcK.js} +2 -3
  53. package/dist/paper-widget-design-Nd5VjI7n.js +4 -0
  54. package/dist/{print-runtime-instance-xGsbD9K-.js → print-runtime-instance-Dckul2Bk.js} +1 -1
  55. package/dist/{print-snapshot-renderer-DYUY1xCI.js → print-snapshot-renderer-lub7u9sp.js} +3 -3
  56. package/dist/{qrcode-design-CO631M71.js → qrcode-design-M0HzGVjM.js} +1 -1
  57. package/dist/{revo-grid.entry-B7SWMhl1.js → revo-grid.entry-Dr4S1tgO.js} +1 -1
  58. package/dist/{revogr-attribution_7.entry-BkqynH6l.js → revogr-attribution_7.entry-27u9hxgM.js} +3 -3
  59. package/dist/{revogr-clipboard_3.entry-DAHR-Vx9.js → revogr-clipboard_3.entry-DxjljgJl.js} +2 -2
  60. package/dist/{revogr-data_4.entry-CVh6lcCy.js → revogr-data_4.entry-CnSalg4D.js} +2 -2
  61. package/dist/{revogr-filter-panel.entry-BBhV4Xqa.js → revogr-filter-panel.entry-CSsekbYc.js} +1 -1
  62. package/dist/seal-design-kuAsmNq1.js +4 -0
  63. package/dist/{serialnumber-design-DxGYVdk3.js → serialnumber-design-DUiLiTSj.js} +1 -1
  64. package/dist/shared/index.es.js +25 -25
  65. package/dist/{single-field-drop-DpHqYP0Z.js → single-field-drop-CF_r0dCX.js} +2 -2
  66. package/dist/{size-editor-D0jQ3Lrf.js → size-editor-DNMqRicI.js} +1 -1
  67. package/dist/src/domain/table/business/material/material-substitution/profile/field-keys.d.ts +1 -37
  68. package/dist/src/domain/table/business/material/material-substitution/runtime/row-change-handlers.d.ts +0 -3
  69. package/dist/src/domain/table/business/preprocess/pretreatment-list/profile/field-keys.d.ts +1 -7
  70. package/dist/src/domain/table/business/sterilize/entrust-steril-batch-list/profile/fields.d.ts +2 -0
  71. package/dist/src/domain/table/design/autofill-expander.d.ts +0 -2
  72. package/dist/src/domain/table/design/hooks/on-field-attach.d.ts +0 -6
  73. package/dist/src/domain/table/index.d.ts +1 -1
  74. package/dist/src/domain/table/types.d.ts +0 -2
  75. package/dist/src/index.d.ts +0 -8
  76. package/dist/src/nocode-base/src/core/factory/sub-table-factory.d.ts +2 -0
  77. package/dist/src/nocode-base/src/core/sub-table/allocate-table-core.d.ts +2 -1
  78. package/dist/src/nocode-base/src/core/sub-table/profile-driven-sub-table-core.d.ts +3 -3
  79. package/dist/src/nocode-base/src/core/sub-table/sub-table-core.d.ts +0 -1
  80. package/dist/src/nocode-base/src/core/sub-table/utils/sterilize/field-keys.d.ts +2 -1
  81. package/dist/src/nocode-base/src/hooks/material-consume/bom-validator.d.ts +9 -7
  82. package/dist/src/nocode-base/src/hooks/material-consume/material-consume-table-controller.d.ts +17 -14
  83. package/dist/src/nocode-base/src/hooks/material-consume/tmpl-bom-controller.d.ts +8 -0
  84. package/dist/src/nocode-base/src/hooks/material-consume/types.d.ts +6 -0
  85. package/dist/src/nocode-base/src/hooks/material-consume-object/initialize-autofill.d.ts +3 -1
  86. package/dist/src/nocode-base/src/hooks/render-page/initialize-runtime.d.ts +7 -3
  87. package/dist/src/nocode-base/src/hooks/render-page/types.d.ts +1 -7
  88. package/dist/src/nocode-base/src/hooks/useCalcFunction.d.ts +2 -8
  89. package/dist/src/nocode-base/src/hooks/useRenderPageFactory.d.ts +6 -46
  90. package/dist/src/nocode-base/src/hooks/useRuntimeInstanceServices.d.ts +0 -21
  91. package/dist/src/nocode-base/src/interface/ref-loader.d.ts +1 -12
  92. package/dist/src/nocode-base/src/interface/transform.d.ts +5 -0
  93. package/dist/src/nocode-base/src/runtime/conversions/v1-runtime.d.ts +1 -1
  94. package/dist/src/nocode-base/src/runtime/formula-utils.d.ts +2 -0
  95. package/dist/src/nocode-base/src/runtime/multi-sheet-runtime.d.ts +3 -1
  96. package/dist/src/nocode-base/src/runtime/runtime-context.d.ts +4 -0
  97. package/dist/src/nocode-base/src/runtime/runtime-field-initializer.d.ts +0 -1
  98. package/dist/src/nocode-base/src/runtime/runtime-field-state.d.ts +2 -5
  99. package/dist/src/nocode-base/src/runtime/runtime-form-state-store.d.ts +6 -2
  100. package/dist/src/nocode-base/src/runtime/runtime-instance-registry.d.ts +5 -5
  101. package/dist/src/nocode-base/src/runtime/table-row-identity.d.ts +2 -0
  102. package/dist/src/nocode-base/src/types/common/base.d.ts +0 -4
  103. package/dist/src/online-form/src/components/device/device-select.vue.d.ts +1 -1
  104. package/dist/src/online-form/src/views/__cell_widgets__/cell-widget-design.vue.d.ts +1 -0
  105. package/dist/src/online-form/src/views/__cell_widgets__/common/quick-search-editor/quick-search.util.d.ts +8 -0
  106. package/dist/src/online-form/src/views/designer/constants/index.d.ts +0 -1
  107. package/dist/src/online-form/src/views/designer/conversions/normalize-paper-grid.d.ts +1 -1
  108. package/dist/src/online-form/src/views/designer/hooks/useAllSpreadSheets.d.ts +35 -124
  109. package/dist/src/online-form/src/views/designer/hooks/useSpreadSheet.d.ts +16 -63
  110. package/dist/src/online-form/src/views/designer/modules/base/designer-wrapper.vue.d.ts +1 -0
  111. package/dist/src/online-form/src/views/designer/modules/duplicate-field-notice.vue.d.ts +2 -0
  112. package/dist/src/online-form/src/views/designer/modules/panel/panel-data-init-config/object-init/hooks/useObjectInit.d.ts +2 -0
  113. package/dist/src/online-form/src/views/designer/modules/panel/sub-table/comps/use-dynamic-sub-table-panel.d.ts +12 -6
  114. package/dist/src/online-form/src/views/designer/modules/xlsx-import-summary.vue.d.ts +11 -0
  115. package/dist/src/online-form/src/views/designer/types/index.d.ts +2 -5
  116. package/dist/src/online-form/src/views/designer/types/sheets.d.ts +2 -0
  117. package/dist/src/online-form/src/views/designer/utils/cell-field-placements.d.ts +12 -0
  118. package/dist/src/online-form/src/views/designer/utils/xlsx-parser.d.ts +9 -3
  119. package/dist/src/online-form/src/views/render/__components__/_field_/_base_/cell/cell-media.vue.d.ts +1 -1
  120. package/dist/src/online-form/src/views/render/__components__/_field_/seal/index.d.ts +0 -1
  121. package/dist/src/online-form/src/views/render/__components__/_field_/trace/composables/useReferenceLabel.d.ts +4 -0
  122. package/dist/src/shared/components/DoubleInput/double-input.vue.d.ts +2 -162
  123. package/dist/src/shared/components/Signature/logic/index.d.ts +0 -14
  124. package/dist/src/shared/enum/field-type.d.ts +2 -7
  125. package/dist/src/shared/utils/cell-wrap.d.ts +9 -0
  126. package/dist/src/shared/utils/field-size.d.ts +2 -0
  127. package/dist/src/shared/utils/grid-size.d.ts +2 -0
  128. package/dist/src/shared/utils/lot2sn.d.ts +14 -1
  129. package/dist/src/shared/utils/query-filter.d.ts +24 -0
  130. package/dist/{sub-table-factory-dhsoO5eF.js → sub-table-factory-D-GcNTOB.js} +112 -209
  131. package/dist/{text-design-CCJVszh9.js → text-design-BfZf4B27.js} +5 -5
  132. package/dist/{throttle-Cpk1LoGk-D7Z-44El.js → throttle-Cpk1LoGk-B4SDzSMU.js} +1 -1
  133. package/dist/{timediff-design-DE0Lb5-J.js → timediff-design-BeO94tLR.js} +1 -2
  134. package/dist/{trace-like-wrapper-u1qMVyxo.js → trace-like-wrapper-Xc4cr21n.js} +5 -3
  135. package/dist/{value-editor.vue_vue_type_style_index_0_lang-BDK70sFY.js → value-editor.vue_vue_type_style_index_0_lang-CMpVHBLK.js} +2 -3
  136. package/dist/web-render/index.es.js +3 -4
  137. package/dist/{widget-barcode-BiqBkpJf.js → widget-barcode-CrfBj8iv.js} +4 -5
  138. package/dist/{widget-diagonal-DEPOR_xL.js → widget-diagonal-C3Nho_Um.js} +3 -4
  139. package/dist/{widget-image-CT0b6oE3.js → widget-image-CjsL9QW8.js} +5 -5
  140. package/dist/{widget-line-CencIyCA.js → widget-line-BtvpVv_s.js} +2 -3
  141. package/dist/{widget-pagination-CLokA4N9.js → widget-pagination-DAUQo2nI.js} +5 -6
  142. package/dist/{widget-power-BPxteor_.js → widget-power-yUHZ4Hoc.js} +3 -4
  143. package/dist/{widget-qrcode-gYHAR233.js → widget-qrcode-DJtT9NaM.js} +3 -4
  144. package/dist/{widget-rangelimit-BJKYDkcT.js → widget-rangelimit-BhadVdCu.js} +3 -3
  145. package/dist/{widget-serialnumber-BCPB7hqo.js → widget-serialnumber-WMHB8nl6.js} +1 -1
  146. package/dist/{widget-text-D_CGo-mQ.js → widget-text-C4dD9JF3.js} +5 -5
  147. package/dist/{widget-timediff-cBekBImJ.js → widget-timediff-C9d8_3hY.js} +2 -3
  148. package/package.json +2 -2
  149. package/dist/paper-widget-design-OVR0zocz.js +0 -4
  150. package/dist/seal-design-BnXd0buM.js +0 -4
  151. package/dist/src/domain/document-business/business/product-release/profile.d.ts +0 -2
  152. package/dist/src/domain/document-business/business/product-release/service.d.ts +0 -2
  153. package/dist/src/domain/document-business/index.d.ts +0 -2
  154. package/dist/src/domain/document-business/registry.d.ts +0 -2
  155. package/dist/src/domain/document-business/runtime/field-query-runtime.d.ts +0 -4
  156. package/dist/src/domain/document-business/types.d.ts +0 -24
  157. package/dist/src/domain/field/number/product-release-qty-manifest.d.ts +0 -2
  158. package/dist/src/domain/field/query-filter.d.ts +0 -15
  159. package/dist/src/domain/table/business/material/material-substitution/runtime/select-loaders.d.ts +0 -8
  160. package/dist/src/domain/table/business/sterilize/entrust-steril-batch-list/profile/field-keys.d.ts +0 -2
  161. package/dist/src/domain/table/business/warehouse/shared/autofill-source-labels.d.ts +0 -19
  162. package/dist/src/nocode-base/src/hooks/formula-params-cache.d.ts +0 -15
  163. package/dist/src/nocode-base/src/hooks/inspection-module-qty.d.ts +0 -4
  164. package/dist/src/nocode-base/src/hooks/render-page/runtime-data-sources.d.ts +0 -45
  165. package/dist/src/nocode-base/src/hooks/render-page/sterilization-date.d.ts +0 -3
  166. package/dist/src/online-form/src/views/designer/utils/placed-fields.d.ts +0 -9
  167. package/dist/src/online-form/src/views/designer/utils/template-placed-fields.d.ts +0 -7
  168. package/dist/src/shared/components/LimitedNumberInput/limited-number-input.vue.d.ts +0 -41
  169. package/dist/src/shared/components/LimitedNumberInput/number-input-rules.d.ts +0 -16
  170. package/dist/src/shared/utils/withRequestCache.d.ts +0 -27
@@ -1,11 +1,10 @@
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";
2
- import { aj as CellWidgetViewState, F as FIELD_TYPE, ba as RenderModeEnum, Z as FormTypeEnum, bG as BpmnNodeTypeEnum, cz as getFieldPlaceholder, bY as MobileFillTypeEnum, C as ComponentTypeEnum, a0 as PlatformEnum, cA as isReferenceOptionActive, p as api, bw as uuid2, c6 as calcUtils, bl as findRuntimeTableRow, ca as ensureTableRowKeys, c3 as bindRuntimeTableColumns, bk as getRowId, cB as FRONT_ROW_KEY, cp as isTableRowKeyMatch, by as isAttachFieldActive, cC as filterRulesByTrigger, cD as isEmptyValue$1, c7 as decodeTableCellRowKey, c9 as ensureFrontRowKey, b2 as getParseRuleInfo, aH as transformUtils, aZ as materialCheck, a_ as getLotLockedReason, a$ as validateReinspectionDate, bp as FormulaRuleFieldKeyEnum, h as SubTableType, b3 as getParseRuleValue, cE as buildError, I as CreateType, bn as findRuntimeParentRow, aK as Dependency_ENUM, aJ as ASSIGNMENTSTRATEGY_ENUM, bL as commonUtils, aO as DeviceLink, a9 as _export_sfc, cj as getRenderedRuntimeTableCell, A as CellType, ct as relocateDeletedRowsToEnd, cF as resetTableRowIdentity, K as useModal, cG as q, cH as QUICK_FILL_ALLOWED_FIELDS, cI as groupFixedTableRows, cJ as processQuickFillRows, cK as getIsGroupEmpty } from "./dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-B7k5famp.js";
3
- import { cloneDeep, isEmpty, has, pickBy, isNil, mergeWith, omit, last, pick, merge } from "lodash-es";
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
+ import { ch as splitRuntimeDataPath, af as CellWidgetViewState, F as FIELD_TYPE, b6 as RenderModeEnum, X as FormTypeEnum, bu as BpmnNodeTypeEnum, ck as getFieldPlaceholder, bK as MobileFillTypeEnum, C as ComponentTypeEnum, be as findRuntimeTableRow, aU as renderUtils, _ as PlatformEnum, E as api, bn as uuid2, bU as calcUtils, bY as ensureTableRowKeys, bR as bindRuntimeTableColumns, bd as getRowId, cl as FRONT_ROW_KEY, cb as isTableRowKeyMatch, au as RangeCompareOp, at as RangeValidateMode, bV as decodeTableCellRowKey, bX as ensureFrontRowKey, b0 as getParseRuleInfo, aD as transformUtils, aW as materialCheck, aX as getLotLockedReason, aY as validateReinspectionDate, bh as FormulaRuleFieldKeyEnum, f as SubTableType, b1 as getParseRuleValue, H as CreateType, bf as findRuntimeParentRow, aG as Dependency_ENUM, aF as ASSIGNMENTSTRATEGY_ENUM, by as commonUtils, aK as DeviceLink, a7 as _export_sfc, c5 as getRenderedRuntimeTableCell, y as CellType, cm as resetTableRowIdentity, J as useModal, cn as q, co as QUICK_FILL_ALLOWED_FIELDS, cp as groupFixedTableRows, cq as processQuickFillRows, cr as getIsGroupEmpty } from "./dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-DEjLEs33.js";
4
3
  import dayjs from "dayjs";
4
+ import { cloneDeep, isEmpty, isNil, pickBy, mergeWith, omit, last, pick, merge } from "lodash-es";
5
5
  import { a as useNamespace, I as Icon } from "./AntdIcon-DCIaV352.js";
6
- import "@gct-paas/form-base";
7
6
  import { Modal, message } from "ant-design-vue";
8
- import { u as useFormModel } from "./mb-render-wAlqnYW9.js";
7
+ import { u as useFormModel } from "./mb-render-sgVmAe6_.js";
9
8
  var MaterialConsumptionPatternEnum = /* @__PURE__ */ ((MaterialConsumptionPatternEnum2) => {
10
9
  MaterialConsumptionPatternEnum2["RECORD"] = "record";
11
10
  MaterialConsumptionPatternEnum2["BOM"] = "bom";
@@ -18,6 +17,26 @@ function normalizeFieldWidth(value, fallback = DEFAULT_FIELD_WIDTH) {
18
17
  const width = Number(value);
19
18
  return Number.isFinite(width) && width >= 0 ? width : fallback;
20
19
  }
20
+ function normalizeFieldFontSize(value, fallback = 12) {
21
+ const defaultSize = `${Number.isFinite(fallback) && fallback > 0 ? fallback : 12}px`;
22
+ if (typeof value === "number") {
23
+ return Number.isFinite(value) && value > 0 ? `${value}px` : defaultSize;
24
+ }
25
+ const size = value?.trim() ?? "";
26
+ if (/^(?:\d+(?:\.\d+)?|\.\d+)(?:px|pt|pc|em|rem|ex|ch|lh|rlh|vw|vh|vmin|vmax|cm|mm|in|%)?$/i.test(
27
+ size
28
+ )) {
29
+ if (Number.parseFloat(size) > 0) {
30
+ return /^\d*\.?\d+$/.test(size) ? `${size}px` : size;
31
+ }
32
+ }
33
+ if (/^(?:xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large|smaller|larger)$/i.test(
34
+ size
35
+ )) {
36
+ return size;
37
+ }
38
+ return defaultSize;
39
+ }
21
40
  function isBlank$1(value) {
22
41
  return value === void 0 || value === null || value === "";
23
42
  }
@@ -98,8 +117,8 @@ function getRuntimeDependencyOutputKey(widgetId, type4, rowPath) {
98
117
  return JSON.stringify([widgetId, type4, rowPath]);
99
118
  }
100
119
  function pathMatches(source, changedPath, structureOnly = false) {
101
- const expected = source.split(".");
102
- const changed = changedPath.split(".");
120
+ const expected = splitRuntimeDataPath(source);
121
+ const changed = splitRuntimeDataPath(changedPath);
103
122
  if (structureOnly && changed.length > expected.length) return false;
104
123
  return expected.slice(0, Math.min(expected.length, changed.length)).every((part, index) => part === "*" || part === changed[index]);
105
124
  }
@@ -202,7 +221,9 @@ class RuntimeDependencyService {
202
221
  }
203
222
  schedule(change) {
204
223
  if (this.disposed) return;
205
- if (change.source === "restore") change = { ...change, paths: ["*"] };
224
+ const labelsOnly = change.paths.length > 0 && change.paths.every((path) => path.endsWith("_lb_"));
225
+ if (change.source === "restore" && change.restoreScope !== "fields" && !labelsOnly)
226
+ change = { ...change, paths: ["*"] };
206
227
  this.effects.forEach((effect) => {
207
228
  if (this.matches(effect, change.paths)) this.cancelExecution(effect.id);
208
229
  });
@@ -258,7 +279,7 @@ class RuntimeDependencyService {
258
279
  await Promise.allSettled(jobs);
259
280
  }
260
281
  }
261
- function resolveRuntimeFieldProps(record, props, widgetId, row, parentRow, formChangeStatus = false) {
282
+ function resolveRuntimeFieldProps(record, props, widgetId, row, parentRow) {
262
283
  const result = { ...props };
263
284
  const { context } = record;
264
285
  const tableField = props.subFieldKey;
@@ -267,11 +288,7 @@ function resolveRuntimeFieldProps(record, props, widgetId, row, parentRow, formC
267
288
  const core = Object.values(context.services.subTableCoreFactory?.coreMap ?? {}).find(
268
289
  (item) => item.subFieldKey === tableField
269
290
  );
270
- const status = core?.calcFieldStatus({
271
- rowData: businessRow,
272
- field: props.field,
273
- formChangeStatus
274
- });
291
+ const status = core?.calcFieldStatus({ rowData: businessRow, field: props.field });
275
292
  if (status?.disabled != null) result.fieldDisabled = status.disabled;
276
293
  if (status?.readonly != null) {
277
294
  result.field_readonly = status.readonly;
@@ -281,7 +298,7 @@ function resolveRuntimeFieldProps(record, props, widgetId, row, parentRow, formC
281
298
  const config = context.businessIndex.fixedTables.find(
282
299
  (table) => table.field === tableField
283
300
  )?.bizTableConfig;
284
- if (!formChangeStatus && config?.dataLockControlField) {
301
+ if (config?.dataLockControlField) {
285
302
  if (props.field === config.dataLockControlField) {
286
303
  if (isPersistedSignatureLockActive(config, businessRow)) {
287
304
  result.field_readonly = true;
@@ -289,7 +306,7 @@ function resolveRuntimeFieldProps(record, props, widgetId, row, parentRow, formC
289
306
  }
290
307
  } else if (isSignatureLockActive(config, businessRow)) result.fieldDisabled = true;
291
308
  }
292
- } else if (!formChangeStatus && !tableField && !props.subModelKey) {
309
+ } else if (!tableField && !props.subModelKey) {
293
310
  result.fieldDisabled ||= context.businessIndex.fixedTables.some(
294
311
  (table) => table.bizTableConfig?.mainFieldBindings?.includes(props.field) && (record.formState.state[table.field] ?? []).some(
295
312
  (item) => isSignatureLockActive(table.bizTableConfig, item)
@@ -397,6 +414,11 @@ function parseRuntimeFieldPath(path) {
397
414
  return void 0;
398
415
  }
399
416
  }
417
+ function isCellAutoLineBreak(style) {
418
+ const whiteSpace = style?.whiteSpace ?? style?.["white-space"];
419
+ const wordBreak = style?.wordBreak ?? style?.["word-break"];
420
+ return whiteSpace === "pre-wrap" && wordBreak === "break-all" || whiteSpace === "pre-line";
421
+ }
400
422
  var NCB_PROVIDE = /* @__PURE__ */ ((NCB_PROVIDE2) => {
401
423
  NCB_PROVIDE2["IS_PDF"] = "NCB_IsPdf";
402
424
  NCB_PROVIDE2["RUNTIME_INSTANCE_REGISTRY"] = "NCB_RuntimeInstanceRegistry";
@@ -425,8 +447,6 @@ function useRuntimeInstanceServices(uniqueIdSource) {
425
447
  instance,
426
448
  /** 控制器负责 Sheet 切换、编辑器收口和提交;尚未挂载时为空。 */
427
449
  controller: computed(() => instance.value?.controller),
428
- /** 全部 Sheet 共享的数源管理器,随实例注册与销毁。 */
429
- dataSourceManager: computed(() => instance.value?.dataSourceManager),
430
450
  /** 表单级配置独立于 Sheet 的 paper;实例未注册时提供空配置。 */
431
451
  formConfig: computed(() => instance.value?.context.formConfig ?? {}),
432
452
  /** 实例切换时重新取对应 Store;读取数据使用 .value.state,写入使用 Store 方法。 */
@@ -512,23 +532,11 @@ function useWidgetStaticAttrs(widget) {
512
532
  const targetFieldId = getRuntimeDataFieldId(widget.props);
513
533
  const fieldState = computed(
514
534
  () => resolveRuntimeFieldState(
515
- resolveRuntimeFieldProps(
516
- instance.value,
517
- widget.props,
518
- widget.id,
519
- void 0,
520
- void 0,
521
- dataRelationShip?.formChangeStatus
522
- ),
535
+ resolveRuntimeFieldProps(instance.value, widget.props, widget.id),
523
536
  dataRelationShip
524
537
  )
525
538
  );
526
- const isAutoLineBreak = computed(() => {
527
- if (!isEmpty(widget.style) && has(widget.style, "whiteSpace") && has(widget.style, "wordBreak") && widget.style.whiteSpace === "pre-wrap" && widget.style.wordBreak === "break-all") {
528
- return true;
529
- }
530
- return false;
531
- });
539
+ const isAutoLineBreak = computed(() => isCellAutoLineBreak(widget.style));
532
540
  return {
533
541
  field,
534
542
  fieldType,
@@ -772,6 +780,49 @@ function getSubTableQuickFillInfo(subTableFieldId, mobileTdIdGroups) {
772
780
  if (!subTableFieldId) return;
773
781
  return assignWidgetInfo(MobileFillTypeEnum.SUB_TABLE, { rowSubFieldKey: subTableFieldId });
774
782
  }
783
+ function getCurrentFormData(_rule, options) {
784
+ if (!_rule._subtableFieldId) return options?.formData;
785
+ return findRuntimeTableRow(options?.formData?.[_rule._subtableFieldId], _rule._rowKey);
786
+ }
787
+ function isSameOptionValue(current, expected) {
788
+ if (typeof expected === "boolean") {
789
+ return renderUtils.getBoolValue(current) === expected;
790
+ }
791
+ if (current === void 0 || current === null || current === "") {
792
+ return false;
793
+ }
794
+ return String(current) === String(expected);
795
+ }
796
+ function isAttachFieldActive(attach, formData) {
797
+ if (attach?.parent && !isAttachFieldActive(attach.parent, formData)) return false;
798
+ if (!attach?.belongFieldId || isNil(attach.optionValue)) {
799
+ return true;
800
+ }
801
+ const row = attach.subtableFieldId ? findRuntimeTableRow(formData?.[attach.subtableFieldId], attach.rowKey) : formData;
802
+ if (attach.subtableFieldId && (!attach.rowKey || !row || row === formData)) {
803
+ return false;
804
+ }
805
+ const raw = row?.[attach.belongFieldId];
806
+ if (attach.multiple) {
807
+ const current = renderUtils.getValue(raw, true);
808
+ if (!Array.isArray(current)) return false;
809
+ return current.some((v) => isSameOptionValue(v, attach.optionValue));
810
+ }
811
+ return isSameOptionValue(raw, attach.optionValue);
812
+ }
813
+ function isReferenceOptionActive(referenceInfo, rowFormData) {
814
+ if (!referenceInfo?.belongFieldId || isNil(referenceInfo.optionValue)) {
815
+ return true;
816
+ }
817
+ return isAttachFieldActive(
818
+ {
819
+ belongFieldId: referenceInfo.belongFieldId,
820
+ optionValue: referenceInfo.optionValue,
821
+ multiple: referenceInfo.multiple
822
+ },
823
+ rowFormData
824
+ );
825
+ }
775
826
  function fieldChromeStyles(state) {
776
827
  const required4 = state === "required";
777
828
  const disabled = state === "disabled";
@@ -814,7 +865,7 @@ function useFieldPresentation(props) {
814
865
  () => dataRelationShip?.platformType === PlatformEnum.INTEGRATION_PAAS_DP
815
866
  );
816
867
  const sizeStyles = computed(() => ({
817
- "--size": typeof widget.style?.fontSize === "number" ? `${widget.style.fontSize}px` : widget.style?.fontSize || `${widget.props.size ?? 12}px`,
868
+ "--size": normalizeFieldFontSize(widget.style?.fontSize, widget.props.size),
818
869
  "--cmp-width": `${normalizeFieldWidth(widget.props.cmpWidth)}px`,
819
870
  "--cmp-height": `${widget.props.cmpHeight ?? 0}px`
820
871
  }));
@@ -923,6 +974,9 @@ function useMaterialBalance() {
923
974
  destoryConsumeModal
924
975
  };
925
976
  }
977
+ function normalizeGridColumnWidth(value) {
978
+ return typeof value === "number" && Number.isFinite(value) ? Math.max(0, value) : 75;
979
+ }
926
980
  function normalizeHistoricalFieldConfig(value) {
927
981
  if (!value || typeof value !== "object") return value;
928
982
  if (Array.isArray(value)) {
@@ -940,10 +994,17 @@ function normalizeHistoricalFieldConfig(value) {
940
994
  const props = result.props;
941
995
  const attachment = props.fieldType === FIELD_TYPE.ATTACHMENT && props.viewState === CellWidgetViewState.Auto;
942
996
  const autofill = Array.isArray(props.autofillRules) && props.enableAutofill === void 0;
943
- if (attachment || autofill) {
997
+ const wrap = result.component === "td" && props.autoLineBreak !== true && isCellAutoLineBreak(result.cellWidget?.style);
998
+ const colsWidth = Array.isArray(props.colsWidth) ? props.colsWidth.map(
999
+ (width) => typeof width === "number" && Number.isFinite(width) ? normalizeGridColumnWidth(width) : width
1000
+ ) : void 0;
1001
+ const columnWidths = colsWidth?.some((width, index) => width !== props.colsWidth[index]);
1002
+ if (attachment || autofill || wrap || columnWidths) {
944
1003
  result = { ...result, props: { ...props } };
945
1004
  if (attachment) result.props.viewState = CellWidgetViewState.Readonly;
946
1005
  if (autofill) result.props.enableAutofill = true;
1006
+ if (wrap) result.props.autoLineBreak = true;
1007
+ if (columnWidths) result.props.colsWidth = colsWidth;
947
1008
  }
948
1009
  }
949
1010
  return result;
@@ -965,8 +1026,6 @@ const LEGACY_RUNTIME_FORM_CONFIG_KEYS = [
965
1026
  "unitConversionRules",
966
1027
  "inspectionDecisionRule",
967
1028
  "customDataSource",
968
- "dataSources",
969
- "fieldFills",
970
1029
  "objectInitialValues",
971
1030
  "javascript",
972
1031
  "checkSignatureConfig",
@@ -1047,16 +1106,17 @@ function validateSheetGraph(sheet) {
1047
1106
  }
1048
1107
  function normalizeSheetMetadata(sheet) {
1049
1108
  const nodes = normalizeHistoricalFieldConfig(sheet.nodes);
1109
+ const sourcePaper = normalizeHistoricalFieldConfig(sheet.paper);
1050
1110
  const paper = {
1051
- ...sheet.paper,
1111
+ ...sourcePaper,
1052
1112
  props: {
1053
- ...sheet.paper.props,
1113
+ ...sourcePaper.props,
1054
1114
  subTableWidgetIds: Object.entries(nodes).filter(([, node]) => node.component === ComponentTypeEnum.SUB_TABLE).map(([id]) => id)
1055
1115
  }
1056
1116
  };
1057
1117
  return { ...sheet, paper, nodes, dataCenter: { [ComponentTypeEnum.PAPER]: paper, ...nodes } };
1058
1118
  }
1059
- function normalizeRuntime(runtime) {
1119
+ function normalizeRuntime(runtime, formType) {
1060
1120
  if (typeof runtime === "string") {
1061
1121
  if (!runtime.trim()) throw new Error("运行时数据不能为空");
1062
1122
  try {
@@ -1067,7 +1127,16 @@ function normalizeRuntime(runtime) {
1067
1127
  }
1068
1128
  assertObject(runtime, "运行时数据格式无效");
1069
1129
  if (runtime.schemaVersion == null || runtime.schemaVersion === 1) {
1070
- const normalized = convertV1Runtime(runtime);
1130
+ const legacyRuntime = formType === FormTypeEnum.FILE && runtime[ComponentTypeEnum.PAPER] == null ? {
1131
+ ...runtime,
1132
+ [ComponentTypeEnum.PAPER]: {
1133
+ id: ComponentTypeEnum.PAPER,
1134
+ component: ComponentTypeEnum.PAPER,
1135
+ props: {},
1136
+ nextIds: []
1137
+ }
1138
+ } : runtime;
1139
+ const normalized = convertV1Runtime(legacyRuntime);
1071
1140
  normalized.sheets.forEach(validateSheetGraph);
1072
1141
  return { ...normalized, sheets: normalized.sheets.map(normalizeSheetMetadata) };
1073
1142
  }
@@ -1204,6 +1273,7 @@ function createRuntimeInstanceContext(options) {
1204
1273
  uniqueId: options.uniqueId,
1205
1274
  instanceId: options.instanceId,
1206
1275
  templateId: options.templateId,
1276
+ formType: options.formType,
1207
1277
  schemaVersion: options.runtime.schemaVersion,
1208
1278
  formConfig: options.runtime.formConfig,
1209
1279
  defaultData: options.defaultData,
@@ -1293,7 +1363,7 @@ class RuntimeSheetService {
1293
1363
  this.calculatingDepth += 1;
1294
1364
  let succeeded = false;
1295
1365
  try {
1296
- const pageData = RuntimeSheetService.calculatePages(sheet.dataCenter, this.formState.state);
1366
+ const pageData = this.context.formType === FormTypeEnum.FILE ? [] : RuntimeSheetService.calculatePages(sheet.dataCenter, this.formState.state);
1297
1367
  this.assertAlive();
1298
1368
  sheet.pageData = pageData;
1299
1369
  sheet.paginationError = void 0;
@@ -1494,6 +1564,7 @@ class RuntimeFormStateStore {
1494
1564
  constructor(initialState, subtableFields = [], tableRelations = []) {
1495
1565
  this.tableRelations = tableRelations;
1496
1566
  this.subtableFields = new Set(subtableFields);
1567
+ normalizeEmptyReferenceLabels(initialState);
1497
1568
  this.subtableFields.forEach((field) => ensureTableRowKeys(initialState[field]));
1498
1569
  bindRuntimeTableColumns(initialState, this.tableRelations);
1499
1570
  this.reactiveState = reactive(initialState);
@@ -1516,7 +1587,7 @@ class RuntimeFormStateStore {
1516
1587
  reactiveState;
1517
1588
  /** 每次成功提交一批变更递增一次,保存和提交用它判断快照是否过期。 */
1518
1589
  revision = 0;
1519
- /** 是否存在尚未保存的变更;restore 来源不会把实例标记为脏。 */
1590
+ /** 是否存在尚未保存的变更;数据恢复及保存回填不会把实例标记为脏。 */
1520
1591
  dirty = false;
1521
1592
  /** 当前嵌套事务深度;只有最外层事务结束时才递增 revision 并通知订阅方。 */
1522
1593
  mutationDepth = 0;
@@ -1524,6 +1595,7 @@ class RuntimeFormStateStore {
1524
1595
  pendingPaths = /* @__PURE__ */ new Set();
1525
1596
  /** 最外层事务的变更来源,嵌套写入沿用该来源。 */
1526
1597
  pendingSource = "system";
1598
+ pendingRestoreScope;
1527
1599
  /** 联动、分页失效、自动保存等实例服务登记的变更监听器。 */
1528
1600
  subscribers = /* @__PURE__ */ new Set();
1529
1601
  /** 用户主动修改过的业务路径,供公式和自动填充执行“不覆盖用户输入”策略。 */
@@ -1648,9 +1720,15 @@ class RuntimeFormStateStore {
1648
1720
  target = this.unwrap(target);
1649
1721
  value = this.unwrap(value);
1650
1722
  this.ensureIncomingRowKeys(target, fieldKey, value);
1651
- if (Object.is(toRaw(this.unwrap(target[fieldKey])), toRaw(value))) return;
1652
- this.mutate([path], source, () => {
1653
- target[fieldKey] = value;
1723
+ const valueChanged = !Object.is(toRaw(this.unwrap(target[fieldKey])), toRaw(value));
1724
+ const labelKey = `${fieldKey}_lb_`;
1725
+ const clearLabel = isEmptyReferenceValue(value) && target[labelKey] != null;
1726
+ if (!valueChanged && !clearLabel) return;
1727
+ const paths = valueChanged ? [path] : [];
1728
+ if (clearLabel) paths.push(`${path}_lb_`);
1729
+ this.mutate(paths, source, () => {
1730
+ if (valueChanged) target[fieldKey] = value;
1731
+ if (clearLabel) target[labelKey] = null;
1654
1732
  });
1655
1733
  }
1656
1734
  /** 合并当前行的一组关联字段,累计稳定业务路径,只提交一次变更。 */
@@ -1669,10 +1747,12 @@ class RuntimeFormStateStore {
1669
1747
  /**
1670
1748
  * 保存后只回填后端身份元数据,不能用仅含 id_/front_row_key_ 的数组覆盖当前业务行。
1671
1749
  * 二维内置复合键可通过原始子行键匹配保存前的本地行。
1750
+ * 保存回填只通知实际变化的字段,不作为整份数据恢复触发全部赋值规则。
1672
1751
  */
1673
1752
  patchSavedMetadata(values) {
1674
- const paths = Object.keys(values);
1675
- this.mutate(paths, "restore", () => this.mergeSavedMetadata(this.reactiveState, values));
1753
+ this.transaction("restore", () => this.mergeSavedMetadata(this.state, values), {
1754
+ restoreScope: "fields"
1755
+ });
1676
1756
  }
1677
1757
  /**
1678
1758
  * 用新对象整体替换实例数据,删除旧对象中多余的顶层字段。
@@ -1681,19 +1761,23 @@ class RuntimeFormStateStore {
1681
1761
  replace(values, source = "restore") {
1682
1762
  const paths = /* @__PURE__ */ new Set([...Object.keys(this.reactiveState), ...Object.keys(values)]);
1683
1763
  this.mutate(Array.from(paths), source, () => {
1764
+ this.userModifiedPaths.clear();
1684
1765
  Object.keys(this.reactiveState).forEach((key) => delete this.reactiveState[key]);
1685
1766
  this.assignValues(this.reactiveState, values);
1767
+ normalizeEmptyReferenceLabels(this.reactiveState);
1686
1768
  });
1687
- this.userModifiedPaths.clear();
1688
1769
  if (source === "restore") this.dirty = false;
1689
1770
  }
1690
1771
  /**
1691
1772
  * 将多次深层写入合并成一次变更提交。
1692
1773
  * 嵌套事务只累计路径,最外层 finally 统一递增 revision 并通知订阅方。
1693
1774
  */
1694
- transaction(source, callback) {
1775
+ transaction(source, callback, options) {
1695
1776
  const outermost = this.mutationDepth === 0;
1696
- if (outermost) this.pendingSource = source;
1777
+ if (outermost) {
1778
+ this.pendingSource = source;
1779
+ this.pendingRestoreScope = source === "restore" ? options?.restoreScope : void 0;
1780
+ }
1697
1781
  this.mutationDepth += 1;
1698
1782
  try {
1699
1783
  return callback(this.state);
@@ -1703,7 +1787,9 @@ class RuntimeFormStateStore {
1703
1787
  const paths = Array.from(this.pendingPaths);
1704
1788
  this.pendingPaths.clear();
1705
1789
  const pendingSource = this.pendingSource;
1790
+ const restoreScope = this.pendingRestoreScope;
1706
1791
  this.pendingSource = "system";
1792
+ this.pendingRestoreScope = void 0;
1707
1793
  try {
1708
1794
  if (paths.some(
1709
1795
  (path) => this.tableRelations.some(
@@ -1716,7 +1802,7 @@ class RuntimeFormStateStore {
1716
1802
  });
1717
1803
  }
1718
1804
  } finally {
1719
- if (paths.length) this.commit(paths, pendingSource);
1805
+ if (paths.length) this.commit(paths, pendingSource, restoreScope);
1720
1806
  }
1721
1807
  }
1722
1808
  }
@@ -1766,10 +1852,15 @@ class RuntimeFormStateStore {
1766
1852
  this.userModifiedPaths.clear();
1767
1853
  }
1768
1854
  /** 提交当前事务积累的路径,更新版本和脏状态,然后同步通知实例服务。 */
1769
- commit(paths, source) {
1855
+ commit(paths, source, restoreScope) {
1770
1856
  this.revision += 1;
1771
1857
  if (source !== "restore") this.dirty = true;
1772
- const change = { revision: this.revision, paths, source };
1858
+ const change = {
1859
+ revision: this.revision,
1860
+ paths,
1861
+ source,
1862
+ ...restoreScope ? { restoreScope } : {}
1863
+ };
1773
1864
  this.subscribers.forEach((subscriber) => subscriber(change));
1774
1865
  }
1775
1866
  /** 如果值是 Store 创建的 scoped view,返回它实际包装的 Vue 响应式目标。 */
@@ -1821,7 +1912,8 @@ class RuntimeFormStateStore {
1821
1912
  if (!target || typeof target !== "object" || Array.isArray(target)) return incoming;
1822
1913
  Object.entries(incoming).forEach(([key, value]) => {
1823
1914
  const childPath = path ? `${path}.${key}` : key;
1824
- target[key] = this.mergeSavedMetadata(target[key], value, childPath);
1915
+ const merged = this.mergeSavedMetadata(target[key], value, childPath);
1916
+ this.setObjectField(target, key, merged, "restore");
1825
1917
  });
1826
1918
  return target;
1827
1919
  }
@@ -1863,6 +1955,23 @@ const ARRAY_MUTATIONS = /* @__PURE__ */ new Set([
1863
1955
  "unshift"
1864
1956
  ]);
1865
1957
  const ARRAY_SEARCHES = /* @__PURE__ */ new Set(["includes", "indexOf", "lastIndexOf"]);
1958
+ function isEmptyReferenceValue(value) {
1959
+ return value == null || value === "" || Array.isArray(value) && value.length === 0;
1960
+ }
1961
+ function normalizeEmptyReferenceLabels(value, visited = /* @__PURE__ */ new WeakSet()) {
1962
+ if (!isMutableRecord(value) || visited.has(toRaw(value))) return;
1963
+ visited.add(toRaw(value));
1964
+ Object.entries(value).forEach(([key, child]) => {
1965
+ if (key.endsWith("_lb_")) {
1966
+ const fieldKey = key.slice(0, -4);
1967
+ if (child != null && Object.prototype.hasOwnProperty.call(value, fieldKey) && isEmptyReferenceValue(value[fieldKey])) {
1968
+ value[key] = null;
1969
+ }
1970
+ } else if (key !== "_DICT") {
1971
+ normalizeEmptyReferenceLabels(child, visited);
1972
+ }
1973
+ });
1974
+ }
1866
1975
  function joinPath(basePath, key) {
1867
1976
  return basePath ? `${basePath}.${key}` : key;
1868
1977
  }
@@ -2141,7 +2250,7 @@ function format(template) {
2141
2250
  function isNativeStringType(type4) {
2142
2251
  return type4 === "string" || type4 === "url" || type4 === "hex" || type4 === "email" || type4 === "date" || type4 === "pattern";
2143
2252
  }
2144
- function isEmptyValue(value, type4) {
2253
+ function isEmptyValue$1(value, type4) {
2145
2254
  if (value === void 0 || value === null) {
2146
2255
  return true;
2147
2256
  }
@@ -2300,7 +2409,7 @@ function deepMerge(target, source) {
2300
2409
  return target;
2301
2410
  }
2302
2411
  var required$1 = function required(rule, value, source, errors, options, type4) {
2303
- if (rule.required && (!source.hasOwnProperty(rule.field) || isEmptyValue(value, type4 || rule.type))) {
2412
+ if (rule.required && (!source.hasOwnProperty(rule.field) || isEmptyValue$1(value, type4 || rule.type))) {
2304
2413
  errors.push(format(options.messages.required, rule.fullField));
2305
2414
  }
2306
2415
  };
@@ -2487,11 +2596,11 @@ var string = function string2(rule, value, callback, source, options) {
2487
2596
  var errors = [];
2488
2597
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2489
2598
  if (validate) {
2490
- if (isEmptyValue(value, "string") && !rule.required) {
2599
+ if (isEmptyValue$1(value, "string") && !rule.required) {
2491
2600
  return callback();
2492
2601
  }
2493
2602
  rules.required(rule, value, source, errors, options, "string");
2494
- if (!isEmptyValue(value, "string")) {
2603
+ if (!isEmptyValue$1(value, "string")) {
2495
2604
  rules.type(rule, value, source, errors, options);
2496
2605
  rules.range(rule, value, source, errors, options);
2497
2606
  rules.pattern(rule, value, source, errors, options);
@@ -2506,7 +2615,7 @@ var method2 = function method3(rule, value, callback, source, options) {
2506
2615
  var errors = [];
2507
2616
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2508
2617
  if (validate) {
2509
- if (isEmptyValue(value) && !rule.required) {
2618
+ if (isEmptyValue$1(value) && !rule.required) {
2510
2619
  return callback();
2511
2620
  }
2512
2621
  rules.required(rule, value, source, errors, options);
@@ -2523,7 +2632,7 @@ var number2 = function number3(rule, value, callback, source, options) {
2523
2632
  if (value === "") {
2524
2633
  value = void 0;
2525
2634
  }
2526
- if (isEmptyValue(value) && !rule.required) {
2635
+ if (isEmptyValue$1(value) && !rule.required) {
2527
2636
  return callback();
2528
2637
  }
2529
2638
  rules.required(rule, value, source, errors, options);
@@ -2538,7 +2647,7 @@ var _boolean = function _boolean2(rule, value, callback, source, options) {
2538
2647
  var errors = [];
2539
2648
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2540
2649
  if (validate) {
2541
- if (isEmptyValue(value) && !rule.required) {
2650
+ if (isEmptyValue$1(value) && !rule.required) {
2542
2651
  return callback();
2543
2652
  }
2544
2653
  rules.required(rule, value, source, errors, options);
@@ -2552,11 +2661,11 @@ var regexp2 = function regexp3(rule, value, callback, source, options) {
2552
2661
  var errors = [];
2553
2662
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2554
2663
  if (validate) {
2555
- if (isEmptyValue(value) && !rule.required) {
2664
+ if (isEmptyValue$1(value) && !rule.required) {
2556
2665
  return callback();
2557
2666
  }
2558
2667
  rules.required(rule, value, source, errors, options);
2559
- if (!isEmptyValue(value)) {
2668
+ if (!isEmptyValue$1(value)) {
2560
2669
  rules.type(rule, value, source, errors, options);
2561
2670
  }
2562
2671
  }
@@ -2566,7 +2675,7 @@ var integer2 = function integer3(rule, value, callback, source, options) {
2566
2675
  var errors = [];
2567
2676
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2568
2677
  if (validate) {
2569
- if (isEmptyValue(value) && !rule.required) {
2678
+ if (isEmptyValue$1(value) && !rule.required) {
2570
2679
  return callback();
2571
2680
  }
2572
2681
  rules.required(rule, value, source, errors, options);
@@ -2581,7 +2690,7 @@ var floatFn = function floatFn2(rule, value, callback, source, options) {
2581
2690
  var errors = [];
2582
2691
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2583
2692
  if (validate) {
2584
- if (isEmptyValue(value) && !rule.required) {
2693
+ if (isEmptyValue$1(value) && !rule.required) {
2585
2694
  return callback();
2586
2695
  }
2587
2696
  rules.required(rule, value, source, errors, options);
@@ -2611,7 +2720,7 @@ var object2 = function object3(rule, value, callback, source, options) {
2611
2720
  var errors = [];
2612
2721
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2613
2722
  if (validate) {
2614
- if (isEmptyValue(value) && !rule.required) {
2723
+ if (isEmptyValue$1(value) && !rule.required) {
2615
2724
  return callback();
2616
2725
  }
2617
2726
  rules.required(rule, value, source, errors, options);
@@ -2626,7 +2735,7 @@ var enumerable2 = function enumerable3(rule, value, callback, source, options) {
2626
2735
  var errors = [];
2627
2736
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2628
2737
  if (validate) {
2629
- if (isEmptyValue(value) && !rule.required) {
2738
+ if (isEmptyValue$1(value) && !rule.required) {
2630
2739
  return callback();
2631
2740
  }
2632
2741
  rules.required(rule, value, source, errors, options);
@@ -2640,11 +2749,11 @@ var pattern2 = function pattern3(rule, value, callback, source, options) {
2640
2749
  var errors = [];
2641
2750
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2642
2751
  if (validate) {
2643
- if (isEmptyValue(value, "string") && !rule.required) {
2752
+ if (isEmptyValue$1(value, "string") && !rule.required) {
2644
2753
  return callback();
2645
2754
  }
2646
2755
  rules.required(rule, value, source, errors, options);
2647
- if (!isEmptyValue(value, "string")) {
2756
+ if (!isEmptyValue$1(value, "string")) {
2648
2757
  rules.pattern(rule, value, source, errors, options);
2649
2758
  }
2650
2759
  }
@@ -2654,11 +2763,11 @@ var date2 = function date3(rule, value, callback, source, options) {
2654
2763
  var errors = [];
2655
2764
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2656
2765
  if (validate) {
2657
- if (isEmptyValue(value, "date") && !rule.required) {
2766
+ if (isEmptyValue$1(value, "date") && !rule.required) {
2658
2767
  return callback();
2659
2768
  }
2660
2769
  rules.required(rule, value, source, errors, options);
2661
- if (!isEmptyValue(value, "date")) {
2770
+ if (!isEmptyValue$1(value, "date")) {
2662
2771
  var dateObject;
2663
2772
  if (value instanceof Date) {
2664
2773
  dateObject = value;
@@ -2684,11 +2793,11 @@ var type2 = function type3(rule, value, callback, source, options) {
2684
2793
  var errors = [];
2685
2794
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2686
2795
  if (validate) {
2687
- if (isEmptyValue(value, ruleType) && !rule.required) {
2796
+ if (isEmptyValue$1(value, ruleType) && !rule.required) {
2688
2797
  return callback();
2689
2798
  }
2690
2799
  rules.required(rule, value, source, errors, options, ruleType);
2691
- if (!isEmptyValue(value, ruleType)) {
2800
+ if (!isEmptyValue$1(value, ruleType)) {
2692
2801
  rules.type(rule, value, source, errors, options);
2693
2802
  }
2694
2803
  }
@@ -2698,7 +2807,7 @@ var any = function any2(rule, value, callback, source, options) {
2698
2807
  var errors = [];
2699
2808
  var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
2700
2809
  if (validate) {
2701
- if (isEmptyValue(value) && !rule.required) {
2810
+ if (isEmptyValue$1(value) && !rule.required) {
2702
2811
  return callback();
2703
2812
  }
2704
2813
  rules.required(rule, value, source, errors, options);
@@ -3035,6 +3144,519 @@ Schema.register = function register(type4, validator) {
3035
3144
  Schema.warning = warning;
3036
3145
  Schema.messages = messages;
3037
3146
  Schema.validators = validators;
3147
+ const stampKeys = [
3148
+ "sealId",
3149
+ "sealName",
3150
+ "sealType",
3151
+ "sealImage",
3152
+ "sealUserId",
3153
+ "sealUserName",
3154
+ "sealUserTime"
3155
+ ];
3156
+ function isSealPosition(value) {
3157
+ if (!value || typeof value !== "object") return false;
3158
+ const p = value;
3159
+ return typeof p.sheetId === "string" && !!p.sheetId && Number.isInteger(p.pageIndex) && p.pageIndex >= 0 && Number.isFinite(p.leftMm) && p.leftMm >= 0 && Number.isFinite(p.topMm) && p.topMm >= 0;
3160
+ }
3161
+ function readSealValue(raw, fallback) {
3162
+ let parsed = {};
3163
+ try {
3164
+ const value = typeof raw === "string" ? JSON.parse(raw || "{}") : raw;
3165
+ if (value && typeof value === "object" && !Array.isArray(value)) parsed = value;
3166
+ } catch {
3167
+ }
3168
+ const stamp = Object.fromEntries(
3169
+ stampKeys.map((key) => [key, typeof parsed[key] === "string" ? parsed[key] : ""])
3170
+ );
3171
+ return {
3172
+ ...stamp,
3173
+ sealPosition: { ...isSealPosition(parsed.sealPosition) ? parsed.sealPosition : fallback }
3174
+ };
3175
+ }
3176
+ function isSealStamped(raw) {
3177
+ try {
3178
+ const value = typeof raw === "string" ? JSON.parse(raw || "{}") : raw;
3179
+ return !!value && typeof value.sealId === "string" && !!value.sealId && typeof value.sealImage === "string" && !!value.sealImage;
3180
+ } catch {
3181
+ return false;
3182
+ }
3183
+ }
3184
+ function isValidSealValue(raw) {
3185
+ try {
3186
+ const value = typeof raw === "string" ? JSON.parse(raw || "{}") : raw;
3187
+ return !!value && stampKeys.every((key) => typeof value[key] === "string") && isSealPosition(value.sealPosition) && (stampKeys.every((key) => !value[key]) || stampKeys.every((key) => !!value[key]));
3188
+ } catch {
3189
+ return false;
3190
+ }
3191
+ }
3192
+ function moveSealValue(raw, fallback, position) {
3193
+ return JSON.stringify({ ...readSealValue(raw, fallback), sealPosition: { ...position } });
3194
+ }
3195
+ function stampSealValue(raw, fallback, stamp) {
3196
+ const current = readSealValue(raw, fallback);
3197
+ const next = readSealValue({ ...stamp, sealPosition: current.sealPosition }, fallback);
3198
+ return JSON.stringify(next);
3199
+ }
3200
+ function clearSealValue(raw, fallback) {
3201
+ return JSON.stringify(
3202
+ readSealValue({ sealPosition: readSealValue(raw, fallback).sealPosition }, fallback)
3203
+ );
3204
+ }
3205
+ function normalizeSealDiameter(value) {
3206
+ const diameter = Number(value);
3207
+ return Number.isFinite(diameter) && diameter > 0 ? Math.min(diameter, 200) : 42;
3208
+ }
3209
+ function clampSealPosition(position, widthMm, heightMm, diameterMm) {
3210
+ return {
3211
+ ...position,
3212
+ leftMm: Math.max(0, Math.min(position.leftMm, Math.max(0, widthMm - diameterMm))),
3213
+ topMm: Math.max(0, Math.min(position.topMm, Math.max(0, heightMm - diameterMm)))
3214
+ };
3215
+ }
3216
+ function initializeSealFields(fields, formData) {
3217
+ for (const { props } of fields) {
3218
+ if (!props.field || props.isFieldModel || props.subFieldKey) continue;
3219
+ const raw = formData[props.field];
3220
+ if (raw == null || raw === "") {
3221
+ formData[props.field] = JSON.stringify(readSealValue("", props.sealPosition));
3222
+ continue;
3223
+ }
3224
+ try {
3225
+ const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
3226
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) continue;
3227
+ if (!isSealPosition(parsed.sealPosition)) {
3228
+ formData[props.field] = JSON.stringify({
3229
+ ...parsed,
3230
+ sealPosition: { ...props.sealPosition }
3231
+ });
3232
+ } else if (typeof raw !== "string") {
3233
+ formData[props.field] = JSON.stringify(parsed);
3234
+ }
3235
+ } catch {
3236
+ }
3237
+ }
3238
+ }
3239
+ const { identify, calculate: calculate$1 } = {
3240
+ identify: (expression) => window.NocodeAdapter.utils?.formulaIdentify?.(expression) ?? [],
3241
+ calculate: (expression, data) => window.NocodeAdapter.utils?.formulaCalculate?.(expression, data)
3242
+ };
3243
+ const getFieldDataValue = (parseInfo, formData) => {
3244
+ const getTextValue = (processedKey, value) => {
3245
+ const textValue = value ?? formData?.[processedKey] ?? "";
3246
+ return Array.isArray(textValue) ? textValue.join() : textValue;
3247
+ };
3248
+ const { type: type4, processed, hashValue } = parseInfo;
3249
+ if (type4 === "hash") {
3250
+ const tableData = toRaw(formData?.[hashValue] || []);
3251
+ return tableData.filter((d) => !d.deleted_).map((row) => getTextValue(processed, row?.[processed])).filter((i) => !isNil(i));
3252
+ }
3253
+ return getTextValue(processed, formData?.[processed]);
3254
+ };
3255
+ const parseFormulaVar = (formulaVar) => {
3256
+ const result = {
3257
+ original: formulaVar,
3258
+ type: "",
3259
+ processed: "",
3260
+ hashValue: "",
3261
+ dataType: ""
3262
+ };
3263
+ if (/^\$([^$]+)\$\.(.+)$/.test(formulaVar)) {
3264
+ const match = formulaVar.match(/^\$([^$]+)\$\.(.+)$/);
3265
+ result.type = "hash";
3266
+ result.processed = match[2];
3267
+ result.hashValue = match[1];
3268
+ result.dataType = "globType";
3269
+ } else if (/^_\.(.+)$/.test(formulaVar)) {
3270
+ const match = formulaVar.match(/^_\.(.+)$/);
3271
+ result.type = "underscore";
3272
+ result.processed = match[1];
3273
+ result.dataType = "currentRowType";
3274
+ } else {
3275
+ result.type = "plain";
3276
+ result.processed = formulaVar;
3277
+ result.dataType = "globType";
3278
+ }
3279
+ return result;
3280
+ };
3281
+ const getParseFormulaVarInfos = (expr) => {
3282
+ const rowArgs = expr ? identify(expr) : [];
3283
+ return {
3284
+ rowArgs,
3285
+ parseInfos: rowArgs.map((curr) => parseFormulaVar(curr))
3286
+ };
3287
+ };
3288
+ const resolveFormulaData = (expr, formData, instanceFormState) => {
3289
+ const rowArgs = identify(expr);
3290
+ const formulaData = isEmpty(rowArgs) ? {} : rowArgs.reduce((total, curr) => {
3291
+ const parseInfo = parseFormulaVar(curr);
3292
+ total[curr] = getFieldDataValue(
3293
+ parseInfo,
3294
+ parseInfo.dataType === "currentRowType" ? formData : instanceFormState
3295
+ );
3296
+ return total;
3297
+ }, {});
3298
+ return formulaData;
3299
+ };
3300
+ const calculateFormula = async (expr, formData, instanceFormState) => calculate$1(expr, resolveFormulaData(expr, formData, instanceFormState));
3301
+ const isEmptyValue = (value) => {
3302
+ return value === void 0 || value === null || typeof value === "string" && value.trim() === "" || Array.isArray(value) && value.length === 0;
3303
+ };
3304
+ const compareByOp = (left, right, op) => {
3305
+ switch (op) {
3306
+ case RangeCompareOp.LT:
3307
+ return left < right;
3308
+ case RangeCompareOp.LE:
3309
+ return left <= right;
3310
+ case RangeCompareOp.GT:
3311
+ return left > right;
3312
+ case RangeCompareOp.GE:
3313
+ default:
3314
+ return left >= right;
3315
+ }
3316
+ };
3317
+ const rangeCompareMessage = (op, val) => {
3318
+ switch (op) {
3319
+ case RangeCompareOp.LT:
3320
+ return $t("sys.fieldValueNotGreaterOrEqual", { val });
3321
+ case RangeCompareOp.LE:
3322
+ return $t("sys.fieldValueNoMoreThan", { val });
3323
+ case RangeCompareOp.GT:
3324
+ return $t("sys.fieldValueNotLessOrEqual", { val });
3325
+ case RangeCompareOp.GE:
3326
+ default:
3327
+ return $t("sys.fieldValueNotLessThan", { val });
3328
+ }
3329
+ };
3330
+ const toUnixTimestamp = (input) => {
3331
+ if (isNil(input) || input === "") return null;
3332
+ const asNumber = typeof input === "number" || typeof input === "string" && /^-?\d+(\.\d+)?$/.test(input.trim());
3333
+ if (asNumber) {
3334
+ const n = Number(input);
3335
+ if (Number.isNaN(n)) return null;
3336
+ const parsed2 = n > 1e12 ? dayjs(n) : dayjs.unix(n);
3337
+ return parsed2.isValid() ? parsed2.unix() : null;
3338
+ }
3339
+ const parsed = dayjs(input);
3340
+ return parsed.isValid() ? parsed.unix() : null;
3341
+ };
3342
+ const buildError = (validatorInfo, message2) => JSON.stringify({ ...validatorInfo, message: message2 });
3343
+ function areValidationCommentsEqual(left, right) {
3344
+ const serialize = (comments) => JSON.stringify(
3345
+ comments,
3346
+ (_key, value) => value && typeof value === "object" && "message" in value ? { ...value, message: value.message } : value
3347
+ );
3348
+ return serialize(left) === serialize(right);
3349
+ }
3350
+ const createRule = (validator, message2, trigger = "change") => ({
3351
+ required: true,
3352
+ validator,
3353
+ message: message2,
3354
+ trigger
3355
+ });
3356
+ function relocateDeletedRowsToEnd(rows = []) {
3357
+ const active = [];
3358
+ const deleted = [];
3359
+ for (const row of rows) {
3360
+ if (row?.deleted_) deleted.push(row);
3361
+ else active.push(row);
3362
+ }
3363
+ return [...active, ...deleted];
3364
+ }
3365
+ function filterRulesByTrigger(rules2, trigger) {
3366
+ return rules2.filter((rule) => {
3367
+ const ruleTrigger = rule.trigger;
3368
+ if (!ruleTrigger) return trigger === "change";
3369
+ if (trigger === "blur") {
3370
+ return ruleTrigger === "blur" || ruleTrigger === "change";
3371
+ }
3372
+ return ruleTrigger === trigger;
3373
+ });
3374
+ }
3375
+ function assembleRules(input) {
3376
+ const { showRequired, fieldType, validatorInfo, props } = input;
3377
+ const {
3378
+ minlength,
3379
+ maxlength,
3380
+ regex,
3381
+ regexHint,
3382
+ validateTrue,
3383
+ validateFalse,
3384
+ enableRangeValidate,
3385
+ maxValidateMode,
3386
+ minValidateMode,
3387
+ maxCompareOp,
3388
+ minCompareOp,
3389
+ minValue,
3390
+ maxValue,
3391
+ minFormulaExpr,
3392
+ maxFormulaExpr,
3393
+ minDate,
3394
+ maxDate,
3395
+ minDateFormulaExpr,
3396
+ maxDateFormulaExpr,
3397
+ maxDateValidateMode,
3398
+ minDateValidateMode
3399
+ } = props;
3400
+ const resolvedMaxCompareOp = maxCompareOp ?? RangeCompareOp.LE;
3401
+ const resolvedMinCompareOp = minCompareOp ?? RangeCompareOp.GE;
3402
+ const RuleProps = [];
3403
+ if (props.bizType === FIELD_TYPE.SEAL) {
3404
+ if (showRequired) {
3405
+ RuleProps.push(
3406
+ createRule(
3407
+ (_rule, value) => isSealStamped(value),
3408
+ buildError(
3409
+ { ...validatorInfo, validationCode: "seal-required" },
3410
+ $t("sys.fieldRequired")
3411
+ ),
3412
+ "manual"
3413
+ )
3414
+ );
3415
+ }
3416
+ RuleProps.push(
3417
+ createRule(
3418
+ (_rule, value) => isEmptyValue(value) || isValidSealValue(value),
3419
+ buildError(validatorInfo, $t("sys.seal.invalid"))
3420
+ )
3421
+ );
3422
+ return RuleProps;
3423
+ }
3424
+ if (showRequired) {
3425
+ RuleProps.push(
3426
+ createRule(
3427
+ (_rule, value) => !isEmptyValue(value),
3428
+ buildError(validatorInfo, $t("sys.fieldRequired")),
3429
+ "manual"
3430
+ )
3431
+ );
3432
+ }
3433
+ if (!isNil(minlength)) {
3434
+ RuleProps.push(
3435
+ createRule((_rule, value) => {
3436
+ if (isEmptyValue(value)) return true;
3437
+ return String(value).length >= minlength;
3438
+ }, buildError(validatorInfo, $t("sys.fieldLengthNotLessThan", { len: minlength })))
3439
+ );
3440
+ }
3441
+ const effectiveMaxlength = isNil(maxlength) && fieldType === FIELD_TYPE.TEXT ? 1024 : maxlength;
3442
+ if (!isNil(effectiveMaxlength)) {
3443
+ RuleProps.push(
3444
+ createRule((_rule, value) => {
3445
+ if (isEmptyValue(value)) return true;
3446
+ return String(value).length <= effectiveMaxlength;
3447
+ }, buildError(validatorInfo, $t("sys.fieldLengthNoMoreThan", { len: effectiveMaxlength })))
3448
+ );
3449
+ }
3450
+ if (regex) {
3451
+ RuleProps.push(
3452
+ createRule((_rule, value) => {
3453
+ if (isEmptyValue(value)) return true;
3454
+ return new RegExp(regex).test(value);
3455
+ }, buildError(validatorInfo, regexHint ?? $t("sys.fieldFormatError")))
3456
+ );
3457
+ }
3458
+ if (validateTrue) {
3459
+ RuleProps.push({
3460
+ required: true,
3461
+ trigger: "manual",
3462
+ validator: (_rule, value) => value === true,
3463
+ message: buildError(validatorInfo, $t("sys.fieldValueNeedTrue"))
3464
+ });
3465
+ }
3466
+ if (validateFalse) {
3467
+ RuleProps.push({
3468
+ required: true,
3469
+ trigger: "manual",
3470
+ validator: (_rule, value) => value === false,
3471
+ message: buildError(validatorInfo, $t("sys.fieldValueNeedFalse"))
3472
+ });
3473
+ }
3474
+ const configuredMinCoversZero = enableRangeValidate && minValidateMode === RangeValidateMode.Fixed_Number && !isEmptyValue(minValue) && Number(minValue) >= 0 && (resolvedMinCompareOp === RangeCompareOp.GE || resolvedMinCompareOp === RangeCompareOp.GT);
3475
+ if (input.defaultMinValue === 0 && !configuredMinCoversZero) {
3476
+ RuleProps.push(
3477
+ createRule(
3478
+ (_rule, value) => isEmptyValue(value) || Number(value) >= 0,
3479
+ buildError(validatorInfo, rangeCompareMessage(RangeCompareOp.GE, 0))
3480
+ )
3481
+ );
3482
+ }
3483
+ if (!enableRangeValidate) {
3484
+ return RuleProps;
3485
+ }
3486
+ if (minValidateMode === RangeValidateMode.Fixed_Number && !isEmptyValue(minValue)) {
3487
+ RuleProps.push(
3488
+ createRule((_rule, value) => {
3489
+ if (isEmptyValue(value)) return true;
3490
+ return compareByOp(Number(value), Number(minValue), resolvedMinCompareOp);
3491
+ }, buildError(validatorInfo, rangeCompareMessage(resolvedMinCompareOp, minValue)))
3492
+ );
3493
+ }
3494
+ if (minValidateMode === RangeValidateMode.Variable_Validate && minFormulaExpr) {
3495
+ RuleProps.push({
3496
+ required: true,
3497
+ trigger: "change",
3498
+ validator: async (_rule, value, _callback, _source, options) => {
3499
+ const currentFormData = getCurrentFormData(_rule, options);
3500
+ const formulaValue = await calculateFormula(
3501
+ minFormulaExpr,
3502
+ currentFormData,
3503
+ options?.formData
3504
+ );
3505
+ if (isEmptyValue(formulaValue)) {
3506
+ return Promise.resolve();
3507
+ }
3508
+ const parsedMin = parseFloat(formulaValue);
3509
+ if (!isNaN(parsedMin)) {
3510
+ if (isEmptyValue(value)) {
3511
+ return Promise.resolve();
3512
+ }
3513
+ if (!compareByOp(Number(value), parsedMin, resolvedMinCompareOp)) {
3514
+ return Promise.reject(
3515
+ new Error(
3516
+ buildError(validatorInfo, rangeCompareMessage(resolvedMinCompareOp, parsedMin))
3517
+ )
3518
+ );
3519
+ }
3520
+ }
3521
+ return Promise.resolve();
3522
+ }
3523
+ });
3524
+ }
3525
+ if (maxValidateMode === RangeValidateMode.Fixed_Number && !isEmptyValue(maxValue)) {
3526
+ RuleProps.push(
3527
+ createRule((_rule, value) => {
3528
+ if (isEmptyValue(value)) return true;
3529
+ return compareByOp(Number(value), Number(maxValue), resolvedMaxCompareOp);
3530
+ }, buildError(validatorInfo, rangeCompareMessage(resolvedMaxCompareOp, maxValue)))
3531
+ );
3532
+ }
3533
+ if (maxValidateMode === RangeValidateMode.Variable_Validate && maxFormulaExpr) {
3534
+ RuleProps.push({
3535
+ required: true,
3536
+ trigger: "change",
3537
+ validator: async (_rule, value, _callback, _source, options) => {
3538
+ const currentFormData = getCurrentFormData(_rule, options);
3539
+ const formulaValue = await calculateFormula(
3540
+ maxFormulaExpr,
3541
+ currentFormData,
3542
+ options?.formData
3543
+ );
3544
+ if (isEmptyValue(formulaValue)) {
3545
+ return Promise.resolve();
3546
+ }
3547
+ const parsedMax = parseFloat(formulaValue);
3548
+ if (!isNaN(parsedMax)) {
3549
+ if (isEmptyValue(value)) {
3550
+ return Promise.resolve();
3551
+ }
3552
+ if (!compareByOp(Number(value), parsedMax, resolvedMaxCompareOp)) {
3553
+ return Promise.reject(
3554
+ new Error(
3555
+ buildError(validatorInfo, rangeCompareMessage(resolvedMaxCompareOp, parsedMax))
3556
+ )
3557
+ );
3558
+ }
3559
+ }
3560
+ return Promise.resolve();
3561
+ }
3562
+ });
3563
+ }
3564
+ if (minDateValidateMode === RangeValidateMode.Fixed_Number && minDate) {
3565
+ RuleProps.push(
3566
+ createRule((_rule, value) => {
3567
+ if (isEmptyValue(value)) return true;
3568
+ const inputTime = dayjs(value).unix();
3569
+ const minTimestamp = dayjs(minDate).unix();
3570
+ if (!dayjs(value).isValid() || !dayjs(minDate).isValid()) return true;
3571
+ return compareByOp(inputTime, minTimestamp, resolvedMinCompareOp);
3572
+ }, buildError(validatorInfo, rangeCompareMessage(resolvedMinCompareOp, minDate)))
3573
+ );
3574
+ }
3575
+ if (maxDateValidateMode === RangeValidateMode.Fixed_Number && maxDate) {
3576
+ RuleProps.push(
3577
+ createRule((_rule, value) => {
3578
+ if (isEmptyValue(value)) return true;
3579
+ const inputTime = dayjs(value).unix();
3580
+ const maxTimestamp = dayjs(maxDate).unix();
3581
+ if (!dayjs(value).isValid() || !dayjs(maxDate).isValid()) return true;
3582
+ return compareByOp(inputTime, maxTimestamp, resolvedMaxCompareOp);
3583
+ }, buildError(validatorInfo, rangeCompareMessage(resolvedMaxCompareOp, maxDate)))
3584
+ );
3585
+ }
3586
+ if (minDateValidateMode === RangeValidateMode.Variable_Validate && minDateFormulaExpr) {
3587
+ RuleProps.push({
3588
+ required: true,
3589
+ trigger: "change",
3590
+ validator: async (_rule, value, _callback, _source, options) => {
3591
+ const currentFormData = getCurrentFormData(_rule, options);
3592
+ const formulaValue = await calculateFormula(
3593
+ minDateFormulaExpr,
3594
+ currentFormData,
3595
+ options?.formData
3596
+ );
3597
+ const limitTime = toUnixTimestamp(formulaValue);
3598
+ if (limitTime !== null) {
3599
+ if (isEmptyValue(value)) {
3600
+ return Promise.resolve();
3601
+ }
3602
+ if (!dayjs(value).isValid()) {
3603
+ return Promise.resolve();
3604
+ }
3605
+ const inputTime = dayjs(value).unix();
3606
+ const fmt = fieldType === FIELD_TYPE.DATE_TIME ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD";
3607
+ if (!compareByOp(inputTime, limitTime, resolvedMinCompareOp)) {
3608
+ return Promise.reject(
3609
+ new Error(
3610
+ buildError(
3611
+ validatorInfo,
3612
+ rangeCompareMessage(resolvedMinCompareOp, dayjs.unix(limitTime).format(fmt))
3613
+ )
3614
+ )
3615
+ );
3616
+ }
3617
+ }
3618
+ return Promise.resolve();
3619
+ }
3620
+ });
3621
+ }
3622
+ if (maxDateValidateMode === RangeValidateMode.Variable_Validate && maxDateFormulaExpr) {
3623
+ RuleProps.push({
3624
+ required: true,
3625
+ trigger: "change",
3626
+ validator: async (_rule, value, _callback, _source, options) => {
3627
+ const currentFormData = getCurrentFormData(_rule, options);
3628
+ const formulaValue = await calculateFormula(
3629
+ maxDateFormulaExpr,
3630
+ currentFormData,
3631
+ options?.formData
3632
+ );
3633
+ const limitTime = toUnixTimestamp(formulaValue);
3634
+ if (limitTime !== null) {
3635
+ if (isEmptyValue(value)) {
3636
+ return Promise.resolve();
3637
+ }
3638
+ if (!dayjs(value).isValid()) {
3639
+ return Promise.resolve();
3640
+ }
3641
+ const inputTime = dayjs(value).unix();
3642
+ const fmt = fieldType === FIELD_TYPE.DATE_TIME ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD";
3643
+ if (!compareByOp(inputTime, limitTime, resolvedMaxCompareOp)) {
3644
+ return Promise.reject(
3645
+ new Error(
3646
+ buildError(
3647
+ validatorInfo,
3648
+ rangeCompareMessage(resolvedMaxCompareOp, dayjs.unix(limitTime).format(fmt))
3649
+ )
3650
+ )
3651
+ );
3652
+ }
3653
+ }
3654
+ return Promise.resolve();
3655
+ }
3656
+ });
3657
+ }
3658
+ return RuleProps;
3659
+ }
3038
3660
  function resolveKeepExceptionHighlight(formValue, fieldValue) {
3039
3661
  if (typeof fieldValue === "boolean") {
3040
3662
  return fieldValue;
@@ -3160,7 +3782,7 @@ function clearResolvedManualErrors(map, resolvePayload) {
3160
3782
  if (!payload) continue;
3161
3783
  const hasManual = filterRulesByTrigger(payload.rules, "manual").length > 0;
3162
3784
  const hasLive = filterRulesByTrigger(payload.rules, "change").length > 0;
3163
- if (hasManual && !hasLive && !isEmptyValue$1(payload.value)) {
3785
+ if (hasManual && !hasLive && !isEmptyValue(payload.value)) {
3164
3786
  delete next[path];
3165
3787
  }
3166
3788
  }
@@ -3174,7 +3796,7 @@ function mergeLiveValidation(current, liveResult, livePaths, resolvePayload) {
3174
3796
  continue;
3175
3797
  }
3176
3798
  const payload = resolvePayload(path);
3177
- const keepManualComment = !!payload && filterRulesByTrigger(payload.rules, "manual").length > 0 && isEmptyValue$1(payload.value) && !!base[path]?.length;
3799
+ const keepManualComment = !!payload && filterRulesByTrigger(payload.rules, "manual").length > 0 && isEmptyValue(payload.value) && !!base[path]?.length;
3178
3800
  if (!keepManualComment) {
3179
3801
  delete base[path];
3180
3802
  }
@@ -3217,7 +3839,7 @@ function mergeDisplayValidation(current, displayResult, ruleKeys, validatedPaths
3217
3839
  next[path] = displayResult[path];
3218
3840
  } else {
3219
3841
  const payload = resolvePayload(path);
3220
- const keepManualComment = !!payload && filterRulesByTrigger(payload.rules, "manual").length > 0 && isEmptyValue$1(payload.value) && !!next[path]?.length;
3842
+ const keepManualComment = !!payload && filterRulesByTrigger(payload.rules, "manual").length > 0 && isEmptyValue(payload.value) && !!next[path]?.length;
3221
3843
  if (!keepManualComment) delete next[path];
3222
3844
  }
3223
3845
  }
@@ -3380,8 +4002,8 @@ class RuntimeValidationService {
3380
4002
  }
3381
4003
  function matchesPattern(pattern4, path) {
3382
4004
  if (!pattern4.includes("*")) return pattern4 === path;
3383
- const expected = pattern4.split(".");
3384
- const actual = path.split(".");
4005
+ const expected = splitRuntimeDataPath(pattern4);
4006
+ const actual = splitRuntimeDataPath(path);
3385
4007
  return expected.length === actual.length && expected.every((part, index) => part === "*" || part === actual[index]);
3386
4008
  }
3387
4009
  class RuntimeFieldRegistry {
@@ -3678,7 +4300,10 @@ class RuntimeInstanceEventBus {
3678
4300
  class RuntimeInstanceRegistry {
3679
4301
  /** 当前渲染入口的加载状态,由工厂更新;PreviewContainer 直接读取,无需宿主额外传参。 */
3680
4302
  loadState = shallowReactive({ loading: false, error: void 0 });
3681
- /** 顶层容器和记录都只做浅响应式;服务类仍保持原始引用。 */
4303
+ /**
4304
+ * 顶层对象使用浅响应式:实例新增、删除需要驱动 Vue 更新;record 内的服务类
4305
+ * 不需要被 Vue 深度代理,各自内部负责自己的响应式状态和生命周期
4306
+ */
3682
4307
  records = shallowReactive({});
3683
4308
  /**
3684
4309
  * 统一托管订阅、watch 和编译结果的取消函数
@@ -3720,9 +4345,8 @@ class RuntimeInstanceRegistry {
3720
4345
  events,
3721
4346
  validation
3722
4347
  };
3723
- const reactiveRecord = shallowReactive(record);
3724
- this.records[context.uniqueId] = reactiveRecord;
3725
- return reactiveRecord;
4348
+ this.records[context.uniqueId] = markRaw(record);
4349
+ return record;
3726
4350
  }
3727
4351
  /**
3728
4352
  * 在页面回调准备完成后挂载实例控制器
@@ -4214,7 +4838,7 @@ class BomEntryValidator {
4214
4838
  this.productCodes[i.product_id_] = i.product_code_;
4215
4839
  });
4216
4840
  }
4217
- this.hasConsumed = this.calcQtyConsumed(this.historyData);
4841
+ this.hasConsumed = this.calcQtyConsumed(this.historyData, "history");
4218
4842
  }
4219
4843
  bomEntry;
4220
4844
  enableSequenceLoading;
@@ -4239,7 +4863,7 @@ class BomEntryValidator {
4239
4863
  }
4240
4864
  /** 需求总量 = 数量倍数 × BOM 单位用量 */
4241
4865
  get total() {
4242
- return this.materialNoNum * this.bomEntry.qty_required_;
4866
+ return this.materialNoNum * Number(this.bomEntry.qty_required_);
4243
4867
  }
4244
4868
  /**
4245
4869
  * 翻译物料的code
@@ -4254,13 +4878,15 @@ class BomEntryValidator {
4254
4878
  * @param arr
4255
4879
  * @return {*}
4256
4880
  */
4257
- filterGroupData(arr) {
4258
- return arr.filter((i) => this.isRowInGroup(i) && i.product_id_);
4881
+ filterGroupData(arr, source = "current") {
4882
+ return arr.filter((i) => this.isRowInGroup(i, source) && i.product_id_);
4259
4883
  }
4260
- /** 行是否属于本 BOM 组(优先 bom_entry_id_,避免跨组 product_id_ 误判) */
4261
- isRowInGroup(row) {
4884
+ /** 按数据来源优先匹配关联标识,无关联标识时按物料判断。 */
4885
+ isRowInGroup(row, source = "current") {
4262
4886
  if (row.deleted_) return false;
4263
- if (row.bom_entry_id_) return row.bom_entry_id_ === this.bomEntry.id_;
4887
+ const entryId = source === "history" ? row.bom_entry_parent_id_ : row.bom_entry_id_;
4888
+ const targetId = source === "history" ? this.bomEntry.parent_id_ : this.bomEntry.id_;
4889
+ if (entryId) return entryId === targetId;
4264
4890
  if (row.product_id_) return this.productIds.includes(row.product_id_);
4265
4891
  return false;
4266
4892
  }
@@ -4391,14 +5017,14 @@ class BomEntryValidator {
4391
5017
  * @param arr
4392
5018
  * @return {*}
4393
5019
  */
4394
- calcQtyConsumed(arr = this.historyData) {
4395
- const groupData = this.filterGroupData(arr);
4396
- return groupData.reduce((acc, cur) => acc + (cur.qty_ ?? 0), 0);
5020
+ calcQtyConsumed(arr = this.historyData, source = "history") {
5021
+ const groupData = this.filterGroupData(arr, source);
5022
+ return groupData.reduce((acc, cur) => acc + Number(cur.qty_ ?? 0), 0);
4397
5023
  }
4398
5024
  /** 上下限校验统一按需求单位口径取转换数量,历史数据未转换时兼容原数量。 */
4399
- calcQtyForBounds(arr) {
4400
- const groupData = this.filterGroupData(arr);
4401
- return groupData.reduce((acc, cur) => acc + (cur.qty_transfer_ ?? cur.qty_ ?? 0), 0);
5025
+ calcQtyForBounds(arr, source = "current") {
5026
+ const groupData = this.filterGroupData(arr, source);
5027
+ return groupData.reduce((acc, cur) => acc + Number(cur.qty_transfer_ ?? cur.qty_ ?? 0), 0);
4402
5028
  }
4403
5029
  /**
4404
5030
  * 计算自定义的数量校验的最大值和最小值
@@ -4413,9 +5039,10 @@ class BomEntryValidator {
4413
5039
  try {
4414
5040
  const json = JSON.parse(str);
4415
5041
  if (json.expr) {
4416
- return await window.gct_expression.execute(json.expr, {
4417
- qty_required_: data.qty_required_
5042
+ const value = await window.gct_expression.execute(json.expr, {
5043
+ qty_required_: data.qty_required_ == null ? data.qty_required_ : Number(data.qty_required_)
4418
5044
  });
5045
+ return value == null ? void 0 : Number(value);
4419
5046
  } else {
4420
5047
  console.warn("没有配置表达式");
4421
5048
  }
@@ -4439,11 +5066,11 @@ class BomEntryValidator {
4439
5066
  return;
4440
5067
  }
4441
5068
  const groupData = this.filterGroupData(arr);
4442
- const loaded = this.calcQtyConsumed(arr);
5069
+ const loaded = this.calcQtyConsumed(arr, "current");
4443
5070
  let required4 = this.remainingNum;
4444
5071
  if (this.isCustomRequiredQty) {
4445
- const currentQty = groupData[0]?.qty_required_;
4446
- if (typeof currentQty !== "number" || !Number.isFinite(currentQty) || currentQty <= 0) {
5072
+ const currentQty = Number(groupData[0]?.qty_required_);
5073
+ if (!Number.isFinite(currentQty) || currentQty <= 0) {
4447
5074
  throw new Error(
4448
5075
  groupNo != null && groupNo > 0 ? `序号${groupNo},需求数量必须大于 0` : "需求数量必须大于 0"
4449
5076
  );
@@ -4472,7 +5099,7 @@ class BomEntryValidator {
4472
5099
  break;
4473
5100
  case "bounds": {
4474
5101
  const groupData2 = this.filterGroupData(arr);
4475
- const consumeSum = this.calcQtyForBounds(arr) + this.calcQtyForBounds(this.historyData);
5102
+ const consumeSum = this.calcQtyForBounds(arr) + this.calcQtyForBounds(this.historyData, "history");
4476
5103
  const { min, max } = await this.calcCustomNumberLimit(groupData2[0]);
4477
5104
  if (min !== void 0 && consumeSum < min || max !== void 0 && consumeSum > max) {
4478
5105
  fail($t("sys.qtyValidationRule.bounds", { min, max }));
@@ -5257,7 +5884,7 @@ function calcGroupRowSpans(rows, validator) {
5257
5884
  function calcGroupQtyConsumedTotal(entryIdx, tableData, validator) {
5258
5885
  if (entryIdx < 0) return 0;
5259
5886
  return tableData.reduce((sum, row) => {
5260
- return validator.resolveEntryIndex(row) === entryIdx ? sum + (row.qty_ ?? 0) : sum;
5887
+ return validator.resolveEntryIndex(row) === entryIdx ? sum + Number(row.qty_ ?? 0) : sum;
5261
5888
  }, 0);
5262
5889
  }
5263
5890
  function syncGroupQtyConsumedTotals(tableData, validator) {
@@ -5356,8 +5983,10 @@ class MaterialConsumeTableController {
5356
5983
  mainFormState = ref({});
5357
5984
  /** 表单数据状态(由 factory bindRuntime 注入):未填报 / STASH / SUBMIT */
5358
5985
  dataStatus;
5359
- /** factory 是否已绑定过运行时(避免重复 initTableData) */
5360
- runtimeBound = false;
5986
+ /** 实例数据只在 LOADED 前准备一次,运行时绑定不再重新生成行。 */
5987
+ initialDataPrepared = false;
5988
+ /** 最近一次同步需求数量时使用的数量依赖。 */
5989
+ syncedMaterialNoNum;
5361
5990
  /** 多 Sheet / 同屏多实例下,弹层和异步交互使用该键隔离。 */
5362
5991
  runtimeOwnerId = "";
5363
5992
  /** 表单是否已暂存或提交(已处理过则不再跑初始化) */
@@ -5508,7 +6137,8 @@ class MaterialConsumeTableController {
5508
6137
  return this.actualBomEntries.map((i) => {
5509
6138
  return {
5510
6139
  product_id_: i.product_id_,
5511
- ...materialNoNum === void 0 ? {} : { qty_required_: i.qty_required_ * materialNoNum },
6140
+ qty_required_uom_id_: i.uom_id_ || void 0,
6141
+ ...materialNoNum === void 0 ? {} : { qty_required_: Number(i.qty_required_) * Number(materialNoNum) },
5512
6142
  bom_entry_id_: i.id_
5513
6143
  };
5514
6144
  });
@@ -5692,6 +6322,9 @@ class MaterialConsumeTableController {
5692
6322
  this.setDefaultValue(row);
5693
6323
  try {
5694
6324
  const plan = await this.bomEntriesValidator.validateScanCanInsert(row, this.actualTableData);
6325
+ if (plan) {
6326
+ row.qty_required_uom_id_ = plan.target.bomEntry.uom_id_ || void 0;
6327
+ }
5695
6328
  const existingRequiredQty = this.isCustomRequiredQty && plan ? this.actualTableData.find(
5696
6329
  (item) => plan.target.isRowInGroup(item) && item.qty_required_ != null
5697
6330
  )?.qty_required_ : void 0;
@@ -5748,40 +6381,36 @@ class MaterialConsumeTableController {
5748
6381
  });
5749
6382
  this.isScanOpen = false;
5750
6383
  }
5751
- /**
5752
- * 打开扫描弹窗
5753
- * @param opts
5754
- */
5755
- async openBomModal() {
5756
- if (!this.actualBomEntries) {
5757
- return;
6384
+ /** Store 创建前准备物料行和数量,全部 Sheet 的 LOADED 共用这份数据。 */
6385
+ prepareInitialData(opts) {
6386
+ if (this.initialDataPrepared) return;
6387
+ this.tableDataRef = toRef(opts.formState, opts.field, []);
6388
+ this.mainFormState = toRef(() => opts.formState);
6389
+ this.dataStatus = opts.dataStatus;
6390
+ this.initTableData(opts.defaultRowData);
6391
+ const rows = this.actualTableData;
6392
+ if (rows.length === 1 && !rows[0].product_id_) {
6393
+ MCDataUtil.setRowEditing(rows[0], true);
5758
6394
  }
5759
- await MaterialConsumeTableController.render?.openBomModal({
5760
- ownerId: this.runtimeOwnerId,
5761
- bomList: this.actualBomEntries,
5762
- onSubstitute: async () => {
5763
- console.log("一键导入数据逻辑");
5764
- }
5765
- });
6395
+ if (this.dataStatus !== "SUBMIT") {
6396
+ this.syncQtyRequiredFromBom();
6397
+ }
6398
+ this.syncedMaterialNoNum = this.materialNoNum;
6399
+ this.initialDataPrepared = true;
5766
6400
  }
5767
- /**
5768
- * 表单加载时由 factory 调用:绑定稳定数据源并初始化行数据。
5769
- * 不在分页组件 setup 中调用,避免跨页挂载重复 init。
5770
- */
6401
+ /** 数量依赖实际变化时才重算,避免首次绑定覆盖 LOADED 中的回填。 */
6402
+ syncQtyRequiredFromBomIfChanged() {
6403
+ if (this.dataStatus === "SUBMIT") return;
6404
+ const materialNoNum = this.materialNoNum;
6405
+ if (this.initialDataPrepared && Object.is(materialNoNum, this.syncedMaterialNoNum)) return;
6406
+ this.syncQtyRequiredFromBom();
6407
+ this.syncedMaterialNoNum = materialNoNum;
6408
+ }
6409
+ /** 只绑定运行时 Store,不重新生成行或修改行内容。 */
5771
6410
  bindRuntime(opts) {
5772
6411
  this.tableDataRef = opts.tableDataRef;
5773
- this.runtimeOwnerId = opts.ownerId;
5774
6412
  this.mainFormState = opts.mainFormState ?? ref({});
5775
6413
  this.dataStatus = opts.dataStatus;
5776
- if (this.runtimeBound) return;
5777
- this.runtimeBound = true;
5778
- this.initTableData(opts.defaultRowData);
5779
- if (this.actualTableData.length === 1) {
5780
- const firstRow = this.actualTableData[0];
5781
- if (!firstRow.product_id_) {
5782
- MCDataUtil.setRowEditing(firstRow, true);
5783
- }
5784
- }
5785
6414
  }
5786
6415
  /**
5787
6416
  * 消耗表组件挂载时调用:只同步视图依赖,不初始化数据、不注册 watch。
@@ -5795,7 +6424,10 @@ class MaterialConsumeTableController {
5795
6424
  * 按当前 materialNoNum 回写各行 qty_required_(校验侧 total 已通过 getter 实时读取)
5796
6425
  */
5797
6426
  syncQtyRequiredFromBom() {
5798
- if (this.tmplBom.required_qty_calc_rule_ === RequiredQtyCalcRule.Custom) return;
6427
+ if (this.tmplBom.required_qty_calc_rule_ === RequiredQtyCalcRule.Custom) {
6428
+ this.updateDerivedQtyFields();
6429
+ return;
6430
+ }
5799
6431
  this.actualTableData.forEach((row) => {
5800
6432
  if (!row.product_id_) return;
5801
6433
  const util = this.bomEntriesValidator.findUtilByProductId(row.product_id_);
@@ -5839,7 +6471,7 @@ class MaterialConsumeTableController {
5839
6471
  const formData = transformFields.reduce((acc, cur) => {
5840
6472
  if (!cur.targetField) return acc;
5841
6473
  if (cur.sourceField === FormulaRuleFieldKeyEnum.INPUT) {
5842
- acc[cur.sourceField] = row.qty_;
6474
+ acc[cur.sourceField] = row.qty_ == null ? row.qty_ : Number(row.qty_);
5843
6475
  } else if (cur.targetField.includes(".")) {
5844
6476
  const fieldKey = cur.targetField.split(".").pop();
5845
6477
  acc[cur.sourceField] = row[fieldKey];
@@ -5851,7 +6483,7 @@ class MaterialConsumeTableController {
5851
6483
  try {
5852
6484
  const res = await calculate(formulaContent, formData);
5853
6485
  Object.assign(row, {
5854
- qty_transfer_: res,
6486
+ qty_transfer_: res == null ? res : Number(res),
5855
6487
  qty_transfer_uom_id_: targetUnitId,
5856
6488
  transfer_formula_: formulaContent
5857
6489
  });
@@ -6035,7 +6667,7 @@ class MaterialConsumeTableController {
6035
6667
  const modifySingleRow = (index) => {
6036
6668
  const row = this.actualTableData[index];
6037
6669
  if (!row.product_id_) {
6038
- row.qty_consumed_ = 0 + (row.qty_ ?? 0);
6670
+ row.qty_consumed_ = Number(row.qty_ ?? 0);
6039
6671
  return;
6040
6672
  }
6041
6673
  let total = 0;
@@ -6044,7 +6676,7 @@ class MaterialConsumeTableController {
6044
6676
  if (util) {
6045
6677
  total += util.hasConsumed;
6046
6678
  util.filterGroupData(beforeArr).forEach((i) => {
6047
- total += i.qty_ ?? 0;
6679
+ total += Number(i.qty_ ?? 0);
6048
6680
  });
6049
6681
  row.qty_consumed_ = total;
6050
6682
  }
@@ -6066,11 +6698,22 @@ class MaterialConsumeTableController {
6066
6698
  this.updateRowConsumed();
6067
6699
  this.updateGroupQtyConsumedTotal();
6068
6700
  }
6701
+ /** 同步 BOM 主物料的需求数量单位,未关联 BOM 的行保留原单位。 */
6702
+ syncRequiredUomFromBom(row) {
6703
+ const validator = this.bomEntriesValidator;
6704
+ const productId = row.product_id_;
6705
+ const bound = row.bom_entry_id_ ? validator.bomEntryValidators.find((item) => item.bomEntry.id_ === row.bom_entry_id_) : void 0;
6706
+ const matched = productId ? bound?.productIds.includes(productId) ? bound : validator.findUtilByProductId(productId) : void 0;
6707
+ if (matched || bound) {
6708
+ row.qty_required_uom_id_ = matched?.bomEntry.uom_id_ || void 0;
6709
+ }
6710
+ }
6069
6711
  /**
6070
- * 设置默认值,如工序,需求数量/已消耗数量
6712
+ * 设置默认值,如工序,需求数量/需求数量单位/已消耗数量
6071
6713
  * @param row
6072
6714
  */
6073
6715
  setDefaultValue(row) {
6716
+ this.syncRequiredUomFromBom(row);
6074
6717
  if (!row.routing_operation_id_) {
6075
6718
  row.routing_operation_id_ = this.tmplBomController.operationId;
6076
6719
  }
@@ -6680,9 +7323,9 @@ class SubTableCore {
6680
7323
  const result = {};
6681
7324
  const config = this.bizTableConfig;
6682
7325
  if (config?.dataLockControlField && params.field === config.dataLockControlField) {
6683
- result.readonly = !params.formChangeStatus && isPersistedSignatureLockActive(config, params.rowData);
7326
+ result.readonly = isPersistedSignatureLockActive(config, params.rowData);
6684
7327
  } else if (config?.dataLockControlField) {
6685
- result.disabled = !params.formChangeStatus && isSignatureLockActive(config, params.rowData);
7328
+ result.disabled = isSignatureLockActive(config, params.rowData);
6686
7329
  }
6687
7330
  return result;
6688
7331
  }
@@ -6827,71 +7470,37 @@ class SubTableCore {
6827
7470
  console.log(this.ctx.widget.props.tableTitle, "处理表单按钮点击事件", params);
6828
7471
  }
6829
7472
  }
6830
- const STORAGE_KEY = "gct:formula:params:v1";
6831
- const PARAMS_CHANGED_EVENT = "gct:formula-params-updated:v1";
6832
- function emptyConfig() {
6833
- return {
6834
- routingParamList: [],
6835
- inspectionParamList: [],
6836
- deviceParamList: []
6837
- };
6838
- }
6839
- function normalizeList(value) {
6840
- if (!Array.isArray(value)) return [];
6841
- return value.filter(
6842
- (item) => item !== null && typeof item === "object" && typeof item.customFieldKey === "string"
6843
- );
6844
- }
6845
- function normalizeConfig(value) {
6846
- const data = value !== null && typeof value === "object" ? value : {};
6847
- return {
6848
- routingParamList: normalizeList(data.routingParamList),
6849
- inspectionParamList: normalizeList(data.inspectionParamList),
6850
- deviceParamList: normalizeList(data.deviceParamList)
6851
- };
6852
- }
6853
- let lastRaw;
6854
- let cachedConfig = emptyConfig();
6855
- function readFormulaParamsConfig() {
6856
- const raw = window.localStorage.getItem(STORAGE_KEY);
6857
- if (raw !== lastRaw) {
6858
- try {
6859
- cachedConfig = normalizeConfig(raw ? JSON.parse(raw) : null);
6860
- } catch {
6861
- cachedConfig = emptyConfig();
6862
- }
6863
- lastRaw = raw;
6864
- }
6865
- return cachedConfig;
7473
+ let currentParamsConfig = {
7474
+ routingParamList: [],
7475
+ inspectionParamList: []
7476
+ };
7477
+ function setFormulaParamsConfig(paramsConfig = {}) {
7478
+ currentParamsConfig = paramsConfig ?? {};
6866
7479
  }
6867
- const currentParamsConfig = {
6868
- get routingParamList() {
6869
- return readFormulaParamsConfig().routingParamList;
6870
- },
6871
- get inspectionParamList() {
6872
- return readFormulaParamsConfig().inspectionParamList;
7480
+ async function CALC_IS_QUALIFIED(key, value, paramList) {
7481
+ if (!key || value == null) {
7482
+ return null;
6873
7483
  }
7484
+ const config = paramList?.find((e) => e.customFieldKey === key);
7485
+ if (!config) return null;
7486
+ const { upperLimit, lowerLimit } = config;
7487
+ if (lowerLimit == null || upperLimit == null) return null;
7488
+ const actual = Number(value);
7489
+ const min = Number(config.lowerLimit);
7490
+ const max = Number(config.upperLimit);
7491
+ if (![actual, min, max].every(Number.isFinite)) return null;
7492
+ return actual >= min && actual <= max;
7493
+ }
7494
+ const FORMULA_FUNCS = {
7495
+ RoutingParamCheck: (key, value) => CALC_IS_QUALIFIED(key, value, currentParamsConfig.routingParamList || []),
7496
+ InspectionParamCheck: (key, value) => CALC_IS_QUALIFIED(key, value, currentParamsConfig.inspectionParamList || [])
6874
7497
  };
6875
- function setFormulaParamsConfig(paramsConfig = {}) {
6876
- const raw = JSON.stringify(normalizeConfig(paramsConfig));
6877
- if (window.localStorage.getItem(STORAGE_KEY) === raw) return;
6878
- window.localStorage.setItem(STORAGE_KEY, raw);
6879
- window.dispatchEvent(new Event(PARAMS_CHANGED_EVENT));
6880
- }
6881
- const boundCalculators = /* @__PURE__ */ new WeakSet();
6882
- function bindFormulaCacheInvalidation(value) {
6883
- if (typeof value !== "function") return;
6884
- const calculator = value;
6885
- if (typeof calculator.clear !== "function" || boundCalculators.has(calculator)) return;
6886
- boundCalculators.add(calculator);
6887
- const clearCache = () => calculator.clear();
6888
- window.addEventListener(PARAMS_CHANGED_EVENT, clearCache);
6889
- window.addEventListener("storage", (event) => {
6890
- if (event.storageArea === window.localStorage && (event.key === STORAGE_KEY || event.key === null)) {
6891
- clearCache();
6892
- }
7498
+ function registerFormulaFuncs() {
7499
+ const register2 = window.NocodeAdapter.utils?.formulaRegister;
7500
+ if (!register2) return;
7501
+ Object.entries(FORMULA_FUNCS).forEach(([k, func]) => {
7502
+ register2(k, func);
6893
7503
  });
6894
- clearCache();
6895
7504
  }
6896
7505
  function getGroupProductIds(entry) {
6897
7506
  const ids = [entry.product_id_];
@@ -7334,10 +7943,6 @@ function useNocodeFormWidget(props, emit) {
7334
7943
  ...colIndex !== void 0 ? { colIndex } : {}
7335
7944
  });
7336
7945
  }
7337
- if (eventType === "onChange" && dataRelationShip?.renderModeType === RenderModeEnum.FormMode) {
7338
- const keys = widget.props?.valueChangeDataSourceKeys;
7339
- if (keys?.length) await instance.value?.dataSourceManager?.queryOnValueChange(keys);
7340
- }
7341
7946
  if (eventType === "onBlur" && dataRelationShip?.renderModeType === RenderModeEnum.FormMode && !instance.value?.controller?.preparing) {
7342
7947
  instance.value?.validation.requestLive("blur", true);
7343
7948
  }
@@ -7420,7 +8025,6 @@ function useDependency(widget, props) {
7420
8025
  const { isFieldModel, subFieldKey } = widget.props;
7421
8026
  const fieldWidget = ref(cloneDeep(props.widget));
7422
8027
  const { instance, formStateStore } = useRuntimeInstanceServices();
7423
- const basicInfo = inject(NCB_PROVIDE.DATA_RELATION_SHIP);
7424
8028
  const targetFieldId = getRuntimeDataFieldId(widget.props);
7425
8029
  const configDependency = widget.props.componentDependency?.configDependency || {};
7426
8030
  const controlledFormData = computed(() => {
@@ -7439,8 +8043,7 @@ function useDependency(widget, props) {
7439
8043
  props.widget.props,
7440
8044
  props.widget.id,
7441
8045
  row,
7442
- parent,
7443
- basicInfo?.formChangeStatus
8046
+ parent
7444
8047
  );
7445
8048
  },
7446
8049
  (displayProps) => {
@@ -7454,7 +8057,11 @@ function useDependency(widget, props) {
7454
8057
  );
7455
8058
  if (!controlledFormData.value._OPCT) {
7456
8059
  const store = formStateStore.value;
7457
- store.setObjectField(controlledFormData.value, "_OPCT", { _DICT: {} }, "restore");
8060
+ store.transaction(
8061
+ "restore",
8062
+ () => store.setObjectField(controlledFormData.value, "_OPCT", { _DICT: {} }, "restore"),
8063
+ { restoreScope: "fields" }
8064
+ );
7458
8065
  }
7459
8066
  const formRowData = toRef(() => {
7460
8067
  if (isFieldModel) {
@@ -7480,6 +8087,7 @@ function useDependency(widget, props) {
7480
8087
  if (!store) throw new Error("字段组件缺少实例级 FormStateStore");
7481
8088
  const row = store.createScopedView(formRowData.value, formRowPath.value);
7482
8089
  const path = store.getFieldPath(row, targetFieldId);
8090
+ if (assignment_expression) store.markUserModified(path);
7483
8091
  store.setObjectField(row, targetFieldId, val, "user", path);
7484
8092
  if (assignment_expression && strategy === ASSIGNMENTSTRATEGY_ENUM.notCovered && commonUtils.isEmptyValue(val)) {
7485
8093
  store.clearUserModified(path);
@@ -10256,7 +10864,7 @@ const DocumentPaper = /* @__PURE__ */ defineComponent({
10256
10864
  }) : null,
10257
10865
  // 在[固定表]顶部的可见单元格上加装操作按钮
10258
10866
  tableAction: (() => {
10259
- const fixedTableActionVisible = fixedTableInfo?.quickFillVisible && !filledFixedTableKeys.value.includes(fixedTableInfo.subFieldKey);
10867
+ const fixedTableActionVisible = props.basicInfo.renderModeType !== RenderModeEnum.ViewMode && fixedTableInfo?.quickFillVisible && !filledFixedTableKeys.value.includes(fixedTableInfo.subFieldKey);
10260
10868
  return () => fixedTableActionVisible ? createVNode(_sfc_main$2, {
10261
10869
  "tdId": tdId,
10262
10870
  "formState": formState.value,
@@ -10431,116 +11039,135 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
10431
11039
  });
10432
11040
  const DynamicTableAction = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-53d7e66c"]]);
10433
11041
  export {
10434
- setFormulaParamsConfig as $,
10435
- getObjectBomProductQuery as A,
11042
+ registerFormulaFuncs as $,
11043
+ resolveObjectBomEntry as A,
10436
11044
  BorderTD as B,
10437
- normalizeHistoricalAutofillRow as C,
11045
+ runWithFillProduct as C,
10438
11046
  DEFAULT_BOOLEAN_FIELD_WIDTH as D,
10439
- EMPTY_PRODUCT_VERSION_ID as E,
10440
- parseRuntimeFieldPath as F,
10441
- useStyles as G,
10442
- useDependency as H,
10443
- useFieldPresentation as I,
10444
- useRuntimeEditorFlusher as J,
10445
- createRuntimeInstanceContext as K,
10446
- RuntimeInstanceRegistry as L,
11047
+ useNocodeFormWidget as E,
11048
+ applyConsumeObjectTraceChange as F,
11049
+ getObjectBomProductQuery as G,
11050
+ EMPTY_PRODUCT_VERSION_ID as H,
11051
+ normalizeHistoricalAutofillRow as I,
11052
+ readSealValue as J,
11053
+ isSealStamped as K,
11054
+ stampSealValue as L,
10447
11055
  MAX_RUNTIME_SHEETS as M,
10448
11056
  NCB_PROVIDE as N,
10449
- RequiredQtyCalcRule as O,
10450
- DocumentPaper as P,
10451
- DynamicTableAction as Q,
10452
- RuntimeFormStateStore as R,
10453
- ScanParamType as S,
10454
- getRuntimeDataFieldId as T,
10455
- buildRuntimeFieldPath as U,
10456
- resolveRuntimeFieldProps as V,
10457
- resolveRuntimeFieldState as W,
10458
- getRuntimeDependencyOutputKey as X,
10459
- isRowAddedInCurrentFormChange as Y,
10460
- MaterialConsumeTableController as Z,
10461
- _sfc_main$5 as _,
11057
+ isValidSealValue as O,
11058
+ clearSealValue as P,
11059
+ parseRuntimeFieldPath as Q,
11060
+ calculateFormula as R,
11061
+ useStyles as S,
11062
+ useDependency as T,
11063
+ useFieldPresentation as U,
11064
+ useRuntimeEditorFlusher as V,
11065
+ RuntimeFormStateStore as W,
11066
+ createRuntimeInstanceContext as X,
11067
+ RuntimeInstanceRegistry as Y,
11068
+ ScanParamType as Z,
11069
+ RequiredQtyCalcRule as _,
10462
11070
  MAX_RUNTIME_SHEET_TITLE_LENGTH as a,
10463
- normalizeRuntime as a0,
10464
- RuntimeSheetService as a1,
10465
- validateObjectBomQtyOnSubmit as a2,
10466
- closeValidatorPopovers as a3,
10467
- enrichFormChangeRowDetails as a4,
10468
- useMaterialBalance as a5,
10469
- collectFormChangeFieldLocations as a6,
10470
- nextFormChangeRowViewHistoryId as a7,
10471
- DeviceConnector as a8,
10472
- DocumentLoading as a9,
10473
- pickObjectFieldKeys as aA,
10474
- recordSubtableRowAdd as aB,
10475
- recordSubtableRowDelete as aC,
10476
- resolveAnnotationFieldLocation as aD,
10477
- resolveFormChangeRowUi as aE,
10478
- resolveRowFormChangeMark as aF,
10479
- setSelectMobileTdId as aG,
10480
- stripLegacyFormConfigFromPaper as aH,
10481
- SubTableActionMenuTypeEnum as aI,
10482
- getMenuByAction as aJ,
10483
- SubTableActionEnum as aK,
10484
- resolveScanFillData as aL,
10485
- buildDefaultMapFromProfile as aM,
10486
- buildFieldStatusFromProfile as aN,
10487
- getRowHandlersForFieldChange as aO,
10488
- getInsertSubMenu as aP,
10489
- resolveScanAdjustType as aQ,
10490
- resolveScanQty as aR,
10491
- toDateOnly as aS,
10492
- getCopySubMenu as aT,
10493
- resolveScanParsedValue as aU,
10494
- isProductBatchEmptyRow as aV,
10495
- DynamicQuickFillModal as aa,
10496
- FixedQuickFillModal as ab,
10497
- FormTmplConfigController as ac,
10498
- LEGACY_RUNTIME_FORM_CONFIG_KEYS as ad,
10499
- LEGACY_RUNTIME_SHEET_ID as ae,
10500
- LEGACY_RUNTIME_SHEET_TITLE as af,
10501
- MCDataUtil as ag,
10502
- OCR_MODEL_PRECISION_ENUM_KEY as ah,
10503
- RuntimeAsyncTaskCoordinator as ai,
10504
- RuntimeDependencyService as aj,
10505
- RuntimeFieldRegistry as ak,
10506
- RuntimeInstanceEventBus as al,
10507
- RuntimePersistenceCoordinator as am,
10508
- RuntimeValidationService as an,
10509
- SubTableCore as ao,
10510
- buildFormChangeDisplayRows as ap,
10511
- convertV1Runtime as aq,
10512
- detailsHaveFormChangeRowOps as ar,
10513
- extractFormChangeRowDetails as as,
10514
- getFormChangeRowKey as at,
10515
- getFormChangeRowOp as au,
10516
- getSubTableQuickFillInfo as av,
10517
- isAnnLocationSelected as aw,
10518
- isBlank as ax,
10519
- isFormChangeGhostRow as ay,
10520
- normalizeHistoricalFieldConfig as az,
10521
- bindFormulaCacheInvalidation as b,
10522
- currentParamsConfig as c,
10523
- MULTI_SHEET_SCHEMA_VERSION as d,
11071
+ getMenuByAction as a$,
11072
+ moveSealValue as a0,
11073
+ DocumentPaper as a1,
11074
+ DynamicTableAction as a2,
11075
+ _sfc_main$5 as a3,
11076
+ getRuntimeDataFieldId as a4,
11077
+ buildRuntimeFieldPath as a5,
11078
+ resolveRuntimeFieldProps as a6,
11079
+ resolveRuntimeFieldState as a7,
11080
+ assembleRules as a8,
11081
+ isAttachFieldActive as a9,
11082
+ RuntimeDependencyService as aA,
11083
+ RuntimeFieldRegistry as aB,
11084
+ RuntimeInstanceEventBus as aC,
11085
+ RuntimePersistenceCoordinator as aD,
11086
+ RuntimeValidationService as aE,
11087
+ SubTableCore as aF,
11088
+ buildFormChangeDisplayRows as aG,
11089
+ convertV1Runtime as aH,
11090
+ detailsHaveFormChangeRowOps as aI,
11091
+ extractFormChangeRowDetails as aJ,
11092
+ getFormChangeRowKey as aK,
11093
+ getFormChangeRowOp as aL,
11094
+ getSubTableQuickFillInfo as aM,
11095
+ isAnnLocationSelected as aN,
11096
+ isBlank as aO,
11097
+ isFormChangeGhostRow as aP,
11098
+ normalizeHistoricalFieldConfig as aQ,
11099
+ pickObjectFieldKeys as aR,
11100
+ recordSubtableRowAdd as aS,
11101
+ recordSubtableRowDelete as aT,
11102
+ relocateDeletedRowsToEnd as aU,
11103
+ resolveAnnotationFieldLocation as aV,
11104
+ resolveFormChangeRowUi as aW,
11105
+ resolveRowFormChangeMark as aX,
11106
+ setSelectMobileTdId as aY,
11107
+ stripLegacyFormConfigFromPaper as aZ,
11108
+ SubTableActionMenuTypeEnum as a_,
11109
+ getRuntimeDependencyOutputKey as aa,
11110
+ isRowAddedInCurrentFormChange as ab,
11111
+ resolveFormulaData as ac,
11112
+ MaterialConsumeTableController as ad,
11113
+ setFormulaParamsConfig as ae,
11114
+ normalizeRuntime as af,
11115
+ initializeSealFields as ag,
11116
+ RuntimeSheetService as ah,
11117
+ validateObjectBomQtyOnSubmit as ai,
11118
+ areValidationCommentsEqual as aj,
11119
+ closeValidatorPopovers as ak,
11120
+ enrichFormChangeRowDetails as al,
11121
+ useMaterialBalance as am,
11122
+ collectFormChangeFieldLocations as an,
11123
+ nextFormChangeRowViewHistoryId as ao,
11124
+ DeviceConnector as ap,
11125
+ DocumentLoading as aq,
11126
+ DynamicQuickFillModal as ar,
11127
+ FixedQuickFillModal as as,
11128
+ FormTmplConfigController as at,
11129
+ LEGACY_RUNTIME_FORM_CONFIG_KEYS as au,
11130
+ LEGACY_RUNTIME_SHEET_ID as av,
11131
+ LEGACY_RUNTIME_SHEET_TITLE as aw,
11132
+ MCDataUtil as ax,
11133
+ OCR_MODEL_PRECISION_ENUM_KEY as ay,
11134
+ RuntimeAsyncTaskCoordinator as az,
11135
+ MULTI_SHEET_SCHEMA_VERSION as b,
11136
+ SubTableActionEnum as b0,
11137
+ resolveScanFillData as b1,
11138
+ buildDefaultMapFromProfile as b2,
11139
+ buildFieldStatusFromProfile as b3,
11140
+ getRowHandlersForFieldChange as b4,
11141
+ getInsertSubMenu as b5,
11142
+ resolveScanAdjustType as b6,
11143
+ resolveScanQty as b7,
11144
+ toDateOnly as b8,
11145
+ hasSubtableBusinessData as b9,
11146
+ getCopySubMenu as ba,
11147
+ resolveScanParsedValue as bb,
11148
+ isProductBatchEmptyRow as bc,
11149
+ normalizeGridColumnWidth as c,
11150
+ getParseFormulaVarInfos as d,
10524
11151
  createRuntimeDocumentV2 as e,
10525
- findFieldProfile as f,
11152
+ clampSealPosition as f,
10526
11153
  getBusinessFieldKey as g,
10527
- normalizeHistoricalBusinessRow as h,
10528
- DeviceLinkTmplUtil as i,
10529
- normalizeAIOcrTmpl as j,
10530
- useWidgetStaticAttrs as k,
10531
- useRuntimeInstanceServices as l,
10532
- setSelectAnnotationId as m,
10533
- normalizeFieldWidth as n,
10534
- useRuntimeRowState as o,
10535
- getObjectBomMaterialLotQuery as p,
10536
- buildObjectLotExtraQuery as q,
10537
- resolveObjectFieldKeys as r,
11154
+ normalizeSealDiameter as h,
11155
+ normalizeFieldWidth as i,
11156
+ isCellAutoLineBreak as j,
11157
+ findFieldProfile as k,
11158
+ normalizeHistoricalBusinessRow as l,
11159
+ DeviceLinkTmplUtil as m,
11160
+ normalizeFieldFontSize as n,
11161
+ normalizeAIOcrTmpl as o,
11162
+ useWidgetStaticAttrs as p,
11163
+ useRuntimeInstanceServices as q,
11164
+ setSelectAnnotationId as r,
10538
11165
  setSelectValidatorId as s,
10539
- MaterialConsumptionPatternEnum as t,
11166
+ useRuntimeRowState as t,
10540
11167
  useFormTmplConfig as u,
10541
- validateObjectBomForScan as v,
10542
- resolveObjectBomEntry as w,
10543
- runWithFillProduct as x,
10544
- useNocodeFormWidget as y,
10545
- applyConsumeObjectTraceChange as z
11168
+ getObjectBomMaterialLotQuery as v,
11169
+ buildObjectLotExtraQuery as w,
11170
+ resolveObjectFieldKeys as x,
11171
+ MaterialConsumptionPatternEnum as y,
11172
+ validateObjectBomForScan as z
10546
11173
  };