@gct-paas/excel 0.1.25 → 0.1.27

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 (254) hide show
  1. package/dist/{VueVideoPlayer-DrKYCkDg.js → VueVideoPlayer-D5r4RRnv.js} +2 -2
  2. package/dist/{agg-design-8eUd9TWn.js → agg-design-BVxNAUfK.js} +1 -1
  3. package/dist/{agg-props-Cb0GvhgU.js → agg-props-BM1V7-82.js} +1 -1
  4. package/dist/{agg-style-CP9sxtsi.js → agg-style-bu1csor3.js} +1 -1
  5. package/dist/{align-editor-BW22Y-bE.js → align-editor-D2IrDyiX.js} +1 -1
  6. package/dist/{attach-fields-editor-pR59KJbo.js → attach-fields-editor-cbkBKnao.js} +3 -3
  7. package/dist/{barcode-design-CmPxgGJB.js → barcode-design-BRx1bmVT.js} +2 -2
  8. package/dist/base/index.es.js +146 -139
  9. package/dist/{base-font-editor-DQM-NcTv.js → base-font-editor-DvxGgHGz.js} +3 -3
  10. package/dist/{boolean-design-Djbg02Nm.js → boolean-design-bh0IRiJd.js} +20 -7
  11. package/dist/{boolean-props-BX5Ok__q.js → boolean-props-CblOGRwR.js} +3 -3
  12. package/dist/{boolean-style-JY9ijHJV.js → boolean-style-DwRYZG46.js} +4 -4
  13. package/dist/cell-upload-C-xtn3eM.js +38 -0
  14. package/dist/{date-range-editor-MZ464S06.js → date-range-editor-DgRj3qWq.js} +3 -3
  15. package/dist/{date-time-design-BjOmfNvq.js → date-time-design-CmzyZZ0f.js} +1 -1
  16. package/dist/{date-time-props-Bcamjhvb.js → date-time-props-D2g7OYyD.js} +3 -3
  17. package/dist/{date-time-style-C0DUGMEb.js → date-time-style-D1hsou32.js} +1 -1
  18. package/dist/{decimal-design-CyFDgKzS.js → decimal-design-mtrsEocu.js} +1 -1
  19. package/dist/{decimal-display-mode-D9_TH-rg.js → decimal-display-mode-DBBORdt8.js} +2 -2
  20. package/dist/{decimal-props-CeOCpAZR.js → decimal-props-BAnCY6iG.js} +4 -4
  21. package/dist/{decimal-style-Ck-jdxrY.js → decimal-style-B_3SjSrk.js} +1 -1
  22. package/dist/{default-value-editor.vue_vue_type_script_setup_true_name_default-value-editor_lang-CRouimIw.js → default-value-editor.vue_vue_type_script_setup_true_name_default-value-editor_lang-CaXarLgm.js} +3 -3
  23. package/dist/{diagonal-design-DiTtAl48.js → diagonal-design-CcD7fvfW.js} +2 -2
  24. package/dist/{double-design-Ctq8CZYg.js → double-design-7vcqNVyg.js} +1 -1
  25. package/dist/{double-props-DPDPvkaN.js → double-props-B-y0KH2n.js} +4 -4
  26. package/dist/{double-style-wBlYIkRL.js → double-style-CA5tNsrD.js} +1 -1
  27. package/dist/{dynamic-table-action-DizP0cBU.js → dynamic-table-action-C2GfKCbJ.js} +1363 -1079
  28. package/dist/{dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-CM2UpTsb.js → dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-Dti3Kjh8.js} +1531 -501
  29. package/dist/{edit.utils-CXmmCnxE-NznLz-dC.js → edit.utils-CXmmCnxE-Ca3Pb0IU.js} +1 -1
  30. package/dist/{enum-design-C4Xq7qCJ.js → enum-design-QV-rTgR9.js} +20 -8
  31. package/dist/{enum-props-CsbFucZR.js → enum-props-75ShzzCh.js} +4 -4
  32. package/dist/{enum-style-MdRMxg9I.js → enum-style-BMtWgRC6.js} +3 -3
  33. package/dist/excel.css +2359 -1006
  34. package/dist/{exceljs.min-C4tGMm7G.js → exceljs.min-0mQdhEhP.js} +2 -2
  35. package/dist/{expression-design-bZfTH0Gl.js → expression-design-E4gBR1RY.js} +1 -1
  36. package/dist/{expression-props-ScLE3Hxg.js → expression-props-BwPz0GJc.js} +1 -1
  37. package/dist/{expression-style-WyB-Q2SD.js → expression-style-D7o1udLl.js} +1 -1
  38. package/dist/{file-design-KtBYJ4Nl.js → file-design-CY5qOoTr.js} +1 -1
  39. package/dist/{file-props-CADrcb5q.js → file-props-zXWQ1bVe.js} +2 -2
  40. package/dist/{file-style-DJ49yOVY.js → file-style-BxiYD3KK.js} +1 -1
  41. package/dist/{font-editor--TX9pRIW.js → font-editor-Dvzk8M-U.js} +3 -3
  42. package/dist/{image-design-DcVh6ef6.js → image-design-BhK2hIpf.js} +2 -2
  43. package/dist/{image-design-CuzmYS4l.js → image-design-lVRSbqr7.js} +2 -2
  44. package/dist/{image-props-_-hVAoB8.js → image-props-BzWQmFnm.js} +1 -1
  45. package/dist/{image-style-DX7y12ib.js → image-style-COx37YQA.js} +1 -1
  46. package/dist/{index-Dq2fcTKP.js → index--0Kpxacn.js} +1 -1
  47. package/dist/{index-B_KMJFf2.js → index-7I61fuwY.js} +1 -1
  48. package/dist/{index-khkFIIpm.js → index-BKcbh7wy.js} +1 -1
  49. package/dist/{index-qrVXTYo_.js → index-BKl3sdLV.js} +1 -1
  50. package/dist/{index-Df5x-HlG.js → index-BOJ1qa5y.js} +3 -2
  51. package/dist/{index-BcZY4Zoa.js → index-BQkzdAys.js} +1 -1
  52. package/dist/{index-gJYIz_91.js → index-BZUfZUe_.js} +1 -1
  53. package/dist/{index-DOk_dASa.js → index-BcFJ5NMo.js} +1 -1
  54. package/dist/{index-CnT14Ynb.js → index-BfFR4_sj.js} +4 -2
  55. package/dist/{index-4SyFxX28.js → index-Bnw3rp6T.js} +2 -2
  56. package/dist/{index-SXqY_RqM.js → index-BxJDx07D.js} +1 -1
  57. package/dist/{index-BrnfxhFy.js → index-C3vFg5YC.js} +2 -2
  58. package/dist/{index-DEbaoJCi.js → index-C8YcRZdY.js} +1 -1
  59. package/dist/{index-C8Mj5jCg.js → index-CLiI_jbj.js} +1 -1
  60. package/dist/{index-BMZk1B6N.js → index-Cv8PAOND.js} +1 -1
  61. package/dist/{index-B6BE028Z.js → index-CvgNTIj3.js} +14059 -7084
  62. package/dist/{index-BsKF7nen.js → index-CvnUTiu5.js} +2 -2
  63. package/dist/{index-w5US1Xj5.js → index-D1eAo-Nu.js} +1 -1
  64. package/dist/{index-B8jI-pcj.js → index-D4c8S3QX.js} +1 -1
  65. package/dist/{index-BDiGdene.js → index-DJMQPKtC.js} +1 -1
  66. package/dist/{index-BeQJg5FL.js → index-DQUYeRO2.js} +1 -1
  67. package/dist/{index-kKbkxtcq.js → index-DX751NRk.js} +1 -1
  68. package/dist/{index-U5Mlom4N.js → index-D_EbV20_.js} +2 -2
  69. package/dist/{index-DACtl2FJ.js → index-FsRMnSH6.js} +1 -1
  70. package/dist/{index-BavMax9_.js → index-JMdllXCQ.js} +1 -1
  71. package/dist/{index-DbCcmPvf.js → index-LPi5gPDc.js} +3 -2
  72. package/dist/{index-DB0Aqof5.js → index-Xo3mSme0.js} +1 -1
  73. package/dist/{index-BbtrRWC8.js → index-_sBfWkw5.js} +1 -1
  74. package/dist/{index-CV96rqXh.js → index-gZDQm5ZQ.js} +1 -1
  75. package/dist/{index-CC1hotEe.js → index-n08cOEu4.js} +1 -1
  76. package/dist/{index-QqGI4m8P.js → index-sDAMzgHy.js} +2 -1
  77. package/dist/{index-3W1W2CJ2.js → index-uPWALfQF.js} +1 -1
  78. package/dist/{index-GYc693un.js → index-xAiRicc_.js} +193 -79
  79. package/dist/index.es.js +45 -44
  80. package/dist/{integer-design-CHYVLdaZ.js → integer-design-B4_XsKZo.js} +1 -1
  81. package/dist/{integer-props-Cw4Z0TNV.js → integer-props-C6PM1TRQ.js} +5 -5
  82. package/dist/{integer-style-DcxXrUeC.js → integer-style-BEQYgQr6.js} +1 -1
  83. package/dist/mb-render-Cuhqw431.js +252 -0
  84. package/dist/{number-input-ex-CwVf8X9n.js → number-input-ex-C-lDRF5x.js} +2 -2
  85. package/dist/{org-props-9qOKXh9R.js → org-props-COEjPBZu.js} +2 -2
  86. package/dist/{org-style-Cmo_gyi-.js → org-style-BCAm4c-t.js} +1 -1
  87. package/dist/{pagination-design-CwNVuj9q.js → pagination-design-BCbcTaoL.js} +2 -2
  88. package/dist/paper-widget-design-B1eAfVY6.js +4 -0
  89. package/dist/{qrcode-design-DBOXla3J.js → qrcode-design-DsWOsTMb.js} +1 -1
  90. package/dist/{ref-autofill-editor-CnxsKzEs.js → ref-autofill-editor-M4SwZwAT.js} +2 -2
  91. package/dist/{ref-props-BMF-yN1j.js → ref-props-z-4FJ63a.js} +3 -3
  92. package/dist/{ref-style-BY_KCFaF.js → ref-style-Cd4xxgki.js} +1 -1
  93. package/dist/{regex-editor-di2pdExg.js → regex-editor-Clq3qEOM.js} +2 -3
  94. package/dist/{revo-grid.entry-DgxhZfAo.js → revo-grid.entry-mK396nD_.js} +1 -1
  95. package/dist/{revogr-attribution_7.entry-D3UhK-WX.js → revogr-attribution_7.entry-CVFYs2_S.js} +3 -3
  96. package/dist/{revogr-clipboard_3.entry-B-lQshG2.js → revogr-clipboard_3.entry-CXob_C6H.js} +2 -2
  97. package/dist/{revogr-data_4.entry-QcY1FWQH.js → revogr-data_4.entry-DdIOstSg.js} +2 -2
  98. package/dist/{revogr-filter-panel.entry-N7DpGorS.js → revogr-filter-panel.entry-CbN2tKV5.js} +1 -1
  99. package/dist/{select-render-type-editor.vue_vue_type_script_setup_true_lang-CCnCM2og.js → select-render-type-editor.vue_vue_type_script_setup_true_lang-BRaJttUU.js} +2 -2
  100. package/dist/{serialnumber-design-C2u7rTeb.js → serialnumber-design-lwuR-KrB.js} +1 -1
  101. package/dist/shared/index.es.js +26 -26
  102. package/dist/{signature-design-BlksOZ8L.js → signature-design-CWKOqjMe.js} +1 -1
  103. package/dist/{signature-props-DsroCtHM.js → signature-props-B4yndn4q.js} +3 -3
  104. package/dist/{signature-style-DmAhSHYV.js → signature-style-5DImPCv-.js} +1 -1
  105. package/dist/{single-field-drop-Cep_fOic.js → single-field-drop-C0IXAiGz.js} +3 -3
  106. package/dist/{size-editor-CEHzkEnJ.js → size-editor-DKIp_UFV.js} +1 -1
  107. package/dist/src/adapter/adapter.d.ts +4 -0
  108. package/dist/src/assets/svgs/table/index.d.ts +34 -0
  109. package/dist/src/domain/index.d.ts +1 -0
  110. package/dist/src/domain/table/business/check/check-table/index.d.ts +1 -0
  111. package/dist/src/domain/table/business/check/check-table/profile/index.d.ts +3 -0
  112. package/dist/src/domain/table/business/material/material-balance/index.d.ts +1 -0
  113. package/dist/src/domain/table/business/material/material-balance/profile/index.d.ts +3 -0
  114. package/dist/src/domain/table/business/material/material-consume/index.d.ts +1 -0
  115. package/dist/src/domain/table/business/material/material-consume/profile/index.d.ts +3 -0
  116. package/dist/src/domain/table/business/preprocess/pretreatment-list/index.d.ts +1 -0
  117. package/dist/src/domain/table/business/preprocess/pretreatment-list/profile/index.d.ts +3 -0
  118. package/dist/src/domain/table/business/sterilize/entrust-steril-batch-list/index.d.ts +1 -0
  119. package/dist/src/domain/table/business/sterilize/entrust-steril-batch-list/profile/index.d.ts +3 -0
  120. package/dist/src/domain/table/business/warehouse/warehouse-allocate/index.d.ts +1 -0
  121. package/dist/src/domain/table/business/warehouse/warehouse-allocate/profile/index.d.ts +3 -0
  122. package/dist/src/domain/table/business/warehouse/warehouse-in/index.d.ts +1 -0
  123. package/dist/src/domain/table/business/warehouse/warehouse-in/profile/index.d.ts +3 -0
  124. package/dist/src/domain/table/business/warehouse/warehouse-in-out/index.d.ts +1 -0
  125. package/dist/src/domain/table/business/warehouse/warehouse-in-out/profile/index.d.ts +3 -0
  126. package/dist/src/domain/table/business/warehouse/warehouse-inventory/index.d.ts +1 -0
  127. package/dist/src/domain/table/business/warehouse/warehouse-inventory/profile/index.d.ts +3 -0
  128. package/dist/src/domain/table/business/warehouse/warehouse-out/index.d.ts +1 -0
  129. package/dist/src/domain/table/business/warehouse/warehouse-out/profile/index.d.ts +3 -0
  130. package/dist/src/domain/table/data/dynamic-table/index.d.ts +1 -0
  131. package/dist/src/domain/table/data/dynamic-table/profile/index.d.ts +3 -0
  132. package/dist/src/domain/table/data/fixed-table/index.d.ts +1 -0
  133. package/dist/src/domain/table/data/fixed-table/profile/index.d.ts +3 -0
  134. package/dist/src/domain/table/data/two-d-table/index.d.ts +1 -0
  135. package/dist/src/domain/table/data/two-d-table/profile/index.d.ts +3 -0
  136. package/dist/src/domain/table/design/create-subtable.d.ts +14 -0
  137. package/dist/src/domain/table/design/index.d.ts +6 -0
  138. package/dist/src/domain/table/design/label.d.ts +3 -0
  139. package/dist/src/domain/table/design/panel-features.d.ts +16 -0
  140. package/dist/src/domain/table/design/panel-type.d.ts +6 -0
  141. package/dist/src/domain/table/design/ribbon-options.d.ts +38 -0
  142. package/dist/src/domain/table/design/sub-model-matcher.d.ts +10 -0
  143. package/dist/src/domain/table/index.d.ts +8 -0
  144. package/dist/src/domain/table/registry.d.ts +27 -0
  145. package/dist/src/domain/table/types.d.ts +78 -0
  146. package/dist/src/index.d.ts +4 -3
  147. package/dist/src/nocode-base/src/components/document-quick-fill/quick-fill.util.d.ts +0 -1
  148. package/dist/src/nocode-base/src/components/document-sub-table-action/type.d.ts +3 -1
  149. package/dist/src/nocode-base/src/constant/index.d.ts +9 -1
  150. package/dist/src/nocode-base/src/hooks/device-link/controller.d.ts +6 -0
  151. package/dist/src/nocode-base/src/hooks/device-link/types.d.ts +10 -0
  152. package/dist/src/nocode-base/src/hooks/form-tmpl-config/form-tmpl-config-controller.d.ts +16 -0
  153. package/dist/src/nocode-base/src/hooks/material-consume/bom-validator.d.ts +140 -18
  154. package/dist/src/nocode-base/src/hooks/material-consume/index.d.ts +1 -0
  155. package/dist/src/nocode-base/src/hooks/material-consume/material-consume-group-merge.d.ts +20 -0
  156. package/dist/src/nocode-base/src/hooks/material-consume/material-consume-table-controller.d.ts +50 -8
  157. package/dist/src/nocode-base/src/hooks/material-consume/mc-render.d.ts +8 -0
  158. package/dist/src/nocode-base/src/hooks/material-consume/product-id-query.d.ts +31 -0
  159. package/dist/src/nocode-base/src/hooks/material-consume/scan-fill.d.ts +10 -0
  160. package/dist/src/nocode-base/src/hooks/material-consume/scan-validator.d.ts +192 -0
  161. package/dist/src/nocode-base/src/hooks/material-consume/service.d.ts +2 -0
  162. package/dist/src/nocode-base/src/hooks/material-consume/types.d.ts +9 -0
  163. package/dist/src/nocode-base/src/hooks/useDependency.d.ts +2 -3
  164. package/dist/src/nocode-base/src/interface/render.d.ts +2 -1
  165. package/dist/src/nocode-base/src/types/fields/i-trace.d.ts +4 -0
  166. package/dist/src/nocode-base/src/types/render/mc-render.d.ts +8 -0
  167. package/dist/src/nocode-base/src/types/widgets/i-paper.d.ts +2 -0
  168. package/dist/src/nocode-base/src/types/widgets/i-ro.d.ts +16 -0
  169. package/dist/src/nocode-base/src/types/widgets/i-serialnumber.d.ts +4 -0
  170. package/dist/src/nocode-base/src/types/widgets/index.d.ts +1 -1
  171. package/dist/src/nocode-web-render/src/render/index.d.ts +2 -1
  172. package/dist/src/nocode-web-render/src/render/sub-table/common/multi-rows-modal.vue.d.ts +15 -0
  173. package/dist/src/nocode-web-render/src/render/sub-table/material-consume/mc-web-render.d.ts +4 -0
  174. package/dist/src/online-form/src/components/device/device-select.vue.d.ts +1 -1
  175. package/dist/src/online-form/src/views/__cell_widgets__/common/assoc-filter-editor/assoc-filter.util.d.ts +1 -1
  176. package/dist/src/online-form/src/views/designer/constants/index.d.ts +1 -0
  177. package/dist/src/online-form/src/views/designer/enums/index.d.ts +4 -1
  178. package/dist/src/online-form/src/views/designer/hooks/useAllSpreadSheets.d.ts +96 -0
  179. package/dist/src/online-form/src/views/designer/hooks/useCellInlineEditor.d.ts +32 -0
  180. package/dist/src/online-form/src/views/designer/hooks/useSpreadSheet.d.ts +125 -0
  181. package/dist/src/online-form/src/views/designer/modules/base/field-attribute-value.vue.d.ts +27 -0
  182. package/dist/src/online-form/src/views/designer/modules/base/field-panel-breadcrumb-separator.vue.d.ts +2 -0
  183. package/dist/src/online-form/src/views/designer/modules/base/field-panel-chevron.vue.d.ts +5 -0
  184. package/dist/src/online-form/src/views/designer/modules/base/field-panel-text-icon.vue.d.ts +2 -0
  185. package/dist/src/online-form/src/views/designer/modules/modals/inline-media-modal.vue.d.ts +17 -0
  186. package/dist/src/online-form/src/views/designer/modules/panel/panel-data-init-config/common/add-ipaas/parameter-struct/json-expression-editor.vue.d.ts +1 -1
  187. package/dist/src/online-form/src/views/designer/modules/panel/panel-tmpl-config/ai-tmpl/ai-tmpl-card.vue.d.ts +12 -0
  188. package/dist/src/online-form/src/views/designer/modules/panel/panel-tmpl-config/ai-tmpl/ai-tmpl-editor.vue.d.ts +19 -2
  189. package/dist/src/online-form/src/views/designer/modules/panel/panel-tmpl-config/ai-tmpl/identify-param-card.vue.d.ts +10 -0
  190. package/dist/src/online-form/src/views/designer/modules/panel/sub-table/comps/repeating-sub-table-config.vue.d.ts +2 -0
  191. package/dist/src/online-form/src/views/designer/modules/panel/sub-table/comps/sub-table-panel-shell.vue.d.ts +24 -0
  192. package/dist/src/online-form/src/views/designer/modules/panel/sub-table/comps/use-dynamic-sub-table-panel.d.ts +1529 -0
  193. package/dist/src/online-form/src/views/designer/modules/panel/{material-consumption → sub-table/material-consumption}/bom-entry-editor.vue.d.ts +1 -1
  194. package/dist/src/online-form/src/views/designer/modules/panel/{material-consumption → sub-table/material-consumption}/bom-modal.vue.d.ts +1 -1
  195. package/dist/src/online-form/src/views/designer/modules/panel/{panel-check-table → sub-table/panel-check-table}/select-check-ds-modal.vue.d.ts +1 -1
  196. package/dist/src/online-form/src/views/designer/modules/sheet/inline-cell-editor.vue.d.ts +16 -0
  197. package/dist/src/online-form/src/views/designer/modules/sheet/sheet-cell.vue.d.ts +1 -3
  198. package/dist/src/online-form/src/views/designer/modules/toolbar.vue.d.ts +31 -1
  199. package/dist/src/online-form/src/views/designer/modules/toolkit/model-field/add-field-btn.vue.d.ts +2 -0
  200. package/dist/src/online-form/src/views/designer/types/index.d.ts +2 -1
  201. package/dist/src/online-form/src/views/inline-cell/inline-cell-content.vue.d.ts +9 -0
  202. package/dist/src/online-form/src/views/inline-cell/medical-device-icon-labels.d.ts +7 -0
  203. package/dist/src/online-form/src/views/inline-cell/use-inline-icon-catalog.d.ts +57 -0
  204. package/dist/src/shared/components/Scrollbar/src/Scrollbar.vue.d.ts +1 -1
  205. package/dist/src/shared/components/Signature/logic/index.d.ts +4 -0
  206. package/dist/src/shared/enum/field-type.d.ts +7 -1
  207. package/dist/src/shared/enum/index.d.ts +4 -2
  208. package/dist/src/shared/enum/online-form.d.ts +5 -1
  209. package/dist/{text-design-DGqMlbc6.js → text-design-Buv9yt9S.js} +2 -2
  210. package/dist/{text-design-CF73oh7E.js → text-design-Cvkrx7Ay.js} +2 -2
  211. package/dist/{text-props-BsBFt5JJ.js → text-props-CkVBSTXP.js} +4 -5
  212. package/dist/{text-style-Bxl0WhxT.js → text-style-ByQS_L5l.js} +1 -1
  213. package/dist/{throttle-Cpk1LoGk-BAKF8Jrc.js → throttle-Cpk1LoGk-G-XhI3O-.js} +1 -1
  214. package/dist/{timediff-design-Bwegb7jM.js → timediff-design-DDoTcrkV.js} +1 -1
  215. package/dist/{trace-design-x7ZPqdyj.js → trace-design-BCzk8EyB.js} +2 -2
  216. package/dist/{trace-props-BdkfBKqh.js → trace-props-BL3L-jup.js} +60 -48
  217. package/dist/{trace-style-Bpyt1oSq.js → trace-style-BlpFFb55.js} +1 -1
  218. package/dist/{use-namespace-qtLS8nEh.js → use-namespace-BxkK4ofX.js} +1 -12
  219. package/dist/{user-props-BgJ96sjN.js → user-props-B-vYJaSq.js} +13 -6
  220. package/dist/{user-style-5VqcsMzw.js → user-style-CbvEdi3Y.js} +1 -1
  221. package/dist/{value-editor.vue_vue_type_style_index_0_lang-QQVkVpPD.js → value-editor.vue_vue_type_style_index_0_lang-s8AB671m.js} +8 -7
  222. package/dist/{version-select-CXTB_A2k.js → version-select-CgXKULuu.js} +2 -2
  223. package/dist/web-render/index.es.js +75 -6
  224. package/dist/{widget-barcode-O6DzMN-0.js → widget-barcode-DSSIOMEn.js} +4 -4
  225. package/dist/{widget-diagonal-B8CiCiyV.js → widget-diagonal-Ce7X4BVB.js} +4 -4
  226. package/dist/{widget-image-CTmh03Jw.js → widget-image-B07sa8Hv.js} +5 -5
  227. package/dist/{widget-line-BiXxV7Xe.js → widget-line-gfOAwJ73.js} +2 -2
  228. package/dist/{widget-pagination-wvZWVot6.js → widget-pagination-DQT0Hcnv.js} +5 -5
  229. package/dist/{widget-power-Co66IvVp.js → widget-power-DB41Q7HC.js} +4 -4
  230. package/dist/{widget-qrcode-ktbJtgPd.js → widget-qrcode-DPMDGtjU.js} +3 -3
  231. package/dist/{widget-rangelimit-2GcRTXPN.js → widget-rangelimit-BpxO9qfT.js} +4 -4
  232. package/dist/{widget-serialnumber-CaFp4L20.js → widget-serialnumber-CM-Lm2mW.js} +1 -1
  233. package/dist/{widget-text-CVp_fAQf.js → widget-text-DnHhMcYh.js} +5 -5
  234. package/dist/{widget-timediff-cMmyhO7r.js → widget-timediff-CHA6cLPN.js} +2 -2
  235. package/package.json +8 -7
  236. package/dist/cell-upload-DgpCH5mZ.js +0 -34
  237. package/dist/mb-render-jyqRTwAF.js +0 -449
  238. package/dist/paper-widget-design-BtscRL22.js +0 -4
  239. package/dist/src/online-form/src/views/designer/modules/panel/panel-material-stocktake-table.vue.d.ts +0 -2
  240. package/dist/src/online-form/src/views/designer/modules/panel/panel-pretreatment-table.vue.d.ts +0 -2
  241. package/dist/src/online-form/src/views/designer/modules/panel/panel-sterilize-batch-table.vue.d.ts +0 -2
  242. package/dist/src/online-form/src/views/designer/modules/panel/panel-tmpl-config/common/add-tmpl-btn.vue.d.ts +0 -7
  243. /package/dist/src/{online-form/src/views/designer/modules/panel/material-consumption/panel-material-consumption-table.vue.d.ts → nocode-web-render/src/components/print-fill-background-selector.vue.d.ts} +0 -0
  244. /package/dist/src/online-form/src/views/designer/modules/panel/{material-consumption → sub-table/material-consumption}/edit-parse-rule.vue.d.ts +0 -0
  245. /package/dist/src/online-form/src/views/designer/modules/panel/{panel-check-table.vue.d.ts → sub-table/material-consumption/panel-material-consumption-table.vue.d.ts} +0 -0
  246. /package/dist/src/online-form/src/views/designer/modules/panel/{material-consumption → sub-table/material-consumption}/translate-span.vue.d.ts +0 -0
  247. /package/dist/src/online-form/src/views/designer/modules/panel/{material-consumption → sub-table/material-consumption}/use-product-translate.d.ts +0 -0
  248. /package/dist/src/online-form/src/views/designer/modules/panel/{panel-check-table → sub-table/panel-check-table}/add-ds-btn.vue.d.ts +0 -0
  249. /package/dist/src/online-form/src/views/designer/modules/panel/{panel-check-table → sub-table/panel-check-table}/right-list.vue.d.ts +0 -0
  250. /package/dist/src/online-form/src/views/designer/modules/panel/{panel-data-group-2d.vue.d.ts → sub-table/panel-check-table.vue.d.ts} +0 -0
  251. /package/dist/src/online-form/src/views/designer/modules/panel/{panel-data-group.vue.d.ts → sub-table/panel-data-group-2d.vue.d.ts} +0 -0
  252. /package/dist/src/online-form/src/views/designer/modules/panel/{panel-dynamic-table.vue.d.ts → sub-table/panel-data-group.vue.d.ts} +0 -0
  253. /package/dist/src/online-form/src/views/designer/modules/panel/{panel-fixed-table.vue.d.ts → sub-table/panel-fixed-table.vue.d.ts} +0 -0
  254. /package/dist/src/online-form/src/views/designer/modules/panel/{panel-material-balance-table.vue.d.ts → sub-table/panel-repeating-sub-table.vue.d.ts} +0 -0
@@ -1,10 +1,10 @@
1
- import { computed, watch, toRaw, onUnmounted, markRaw, ref, toRef, reactive, inject, provide, defineComponent, openBlock, createElementBlock, mergeProps, unref, createElementVNode, normalizeClass, renderSlot, createCommentVNode, createVNode, toDisplayString, isVNode, h, onBeforeMount, resolveComponent, createBlock, withCtx, Fragment, renderList, createTextVNode, onMounted } from "vue";
2
- import { cloneDeep, has, isNil, merge, defaults, pickBy, mergeWith, omit, last, pick } from "lodash-es";
3
- import { e as ComponentTypeEnum, F as FIELD_TYPE, i as api, aV as ButtonTypeEnum, t as FormTypeEnum, aO as safeParseArray, aq as RenderModeEnum, aQ as mergeByMultiKey, aU as BpmnSignatureTypeEnum, aP as BpmnNodeTypeEnum, ab as useWidgetStaticAttrs, bF as assembleRules, bG as deleteFormRule, bH as setFormRule, aF as requestDisplayValidation, bI as isReferenceOptionActive, bJ as validateAllFields, bK as runValidation, bL as stockCheck, am as getParseRuleInfo, an as getParseRuleValue, bM as materialCheck, ax as calcFillData, as as FormulaRuleFieldKeyEnum, bN as judgeUnique, g as SubTableType, ao as useCurrentPageFormState, R as Dependency_ENUM, Q as ASSIGNMENTSTRATEGY_ENUM, aM as uuid2, a3 as DeviceLink, _ as _export_sfc, aj as NCB_PROVIDE, b7 as buildFormChangeDisplayRows, aR as getRowId, bD as resolveRowFormChangeMark, bC as resolveFormChangeRowUi, bp as isAnnLocationSelected, bE as setSelectMobileTdId, bq as isFormChangeGhostRow, h as CellType, ad as setSelectAnnotationId, bx as recordSubtableRowDelete, b9 as deleteSubtableRow, by as relocateDeletedRowsToEnd, bO as FRONT_ROW_KEY, az as transformUtils, bo as insertSubtableRows, bw as recordSubtableRowAdd, bP as q, bQ as groupFixedTableRows, bR as QUICK_FILL_ALLOWED_FIELDS, bS as processQuickFillRows, bT as getIsGroupEmpty, bj as getSubTableQuickFillInfo } from "./dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-CM2UpTsb.js";
4
- import { u as useFormModel, w as watchDebounced } from "./mb-render-jyqRTwAF.js";
1
+ import { computed, watch, toRaw, onUnmounted, markRaw, ref, reactive, inject, provide, defineComponent, openBlock, createElementBlock, mergeProps, unref, createElementVNode, normalizeClass, renderSlot, createCommentVNode, createVNode, toDisplayString, toRef, isVNode, h, onBeforeMount, resolveComponent, createBlock, withCtx, Fragment, renderList, createTextVNode, onMounted } from "vue";
2
+ import { isNil, cloneDeep, merge, pickBy, mergeWith, omit, last, pick } from "lodash-es";
3
+ import { ag as useWidgetStaticAttrs, e as ComponentTypeEnum, bR as assembleRules, bS as deleteFormRule, bT as setFormRule, aM as requestDisplayValidation, bU as isReferenceOptionActive, bV as validateAllFields, bW as runValidation, bP as stockCheck, bX as ensureFrontRowKey, bY as FRONT_ROW_KEY, aZ as getRowId, ar as getParseRuleInfo, aG as transformUtils, bD as materialCheck, au as getLotLockedReason, az as FormulaRuleFieldKeyEnum, bC as judgeUnique, i as api, g as SubTableType, as as getParseRuleValue, aT as uuid2, a8 as DeviceLink, _ as _export_sfc, ao as NCB_PROVIDE, bf as buildFormChangeDisplayRows, bN as resolveRowFormChangeMark, bM as resolveFormChangeRowUi, bx as isAnnLocationSelected, bO as setSelectMobileTdId, by as isFormChangeGhostRow, h as CellType, ai as setSelectAnnotationId, bH as recordSubtableRowDelete, bh as deleteSubtableRow, bI as relocateDeletedRowsToEnd, bw as insertSubtableRows, bG as recordSubtableRowAdd, at as useCurrentPageFormState, al as renderUtils, k as useModal, bZ as q, b_ as groupFixedTableRows, b$ as QUICK_FILL_ALLOWED_FIELDS, c0 as processQuickFillRows, c1 as getIsGroupEmpty, aw as RenderModeEnum, br as getSubTableQuickFillInfo } from "./dynamic-table-action.vue_vue_type_style_index_0_scoped_53d7e66c_lang-Dti3Kjh8.js";
5
4
  import dayjs from "dayjs";
6
- import { a as useNamespace, u as useModal } from "./use-namespace-qtLS8nEh.js";
5
+ import { u as useNamespace } from "./use-namespace-BxkK4ofX.js";
7
6
  import { Modal, message } from "ant-design-vue";
7
+ import { u as useFormModel } from "./mb-render-Cuhqw431.js";
8
8
  const InstanceStatusValues = {
9
9
  /** 作废状态 */
10
10
  ABANDON: "ABANDON",
@@ -55,7 +55,7 @@ function useStyles(widget, isArea = false) {
55
55
  cls.push("m-justify-end");
56
56
  }
57
57
  } else {
58
- cls.push("m-justify-start");
58
+ cls.push("m-justify-center");
59
59
  }
60
60
  if (widget.style["verticalAlign"]) {
61
61
  if (widget.style["verticalAlign"] === "middle") {
@@ -68,600 +68,19 @@ function useStyles(widget, isArea = false) {
68
68
  cls.push(isArea ? "m-content-end" : "m-items-end");
69
69
  }
70
70
  } else {
71
- cls.push(isArea ? "m-content-start" : "m-items-start");
71
+ cls.push(isArea ? "m-content-center" : "m-items-center");
72
72
  }
73
73
  return cls;
74
74
  });
75
75
  return { otherClass };
76
76
  }
77
- const commonUtils = {
78
- /** 列表转成树 */
79
- listTransformTree: (list) => {
80
- const cloneData = cloneDeep(list);
81
- const result = [];
82
- const map = /* @__PURE__ */ new Map();
83
- cloneData.forEach((item) => {
84
- map.set(item.id, { ...item, selectable: item.type === "DOC", children: [] });
85
- });
86
- cloneData.forEach((item) => {
87
- const node = map.get(item.id);
88
- if (item.rootNode) {
89
- result.push(node);
90
- } else {
91
- const parent = map.get(item.parentId);
92
- if (parent) {
93
- parent.children.push(node);
94
- }
95
- }
96
- });
97
- return result;
98
- },
99
- findFirstDoc: (tree, ofId) => {
100
- const cloneTree = cloneDeep(tree);
101
- const queue = [...cloneTree];
102
- while (queue.length > 0) {
103
- const node = queue.shift();
104
- if (node.type === "DOC" || !node.type) {
105
- if (ofId) {
106
- if (node.id === ofId || node.tmplId === ofId) {
107
- return node;
108
- }
109
- } else {
110
- return node;
111
- }
112
- }
113
- if (node.children && node.children.length > 0) {
114
- queue.push(...node.children);
115
- }
116
- }
117
- return null;
118
- },
119
- uuid2: (len, radix) => {
120
- const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
121
- let uuid = [], i;
122
- radix = radix || chars.length;
123
- if (len) {
124
- for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
125
- } else {
126
- let r;
127
- uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-";
128
- uuid[14] = "4";
129
- for (i = 0; i < 36; i++) {
130
- if (!uuid[i]) {
131
- r = 0 | Math.random() * 16;
132
- uuid[i] = chars[i == 19 ? r & 3 | 8 : r];
133
- }
134
- }
135
- }
136
- return uuid.join("");
137
- },
138
- isEmptyValue: (value) => {
139
- return value === void 0 || value === null || typeof value === "string" && value.trim() === "" || Array.isArray(value) && value.length === 0;
140
- },
141
- get gctInstanceStatusTheme() {
142
- return {
143
- "gct-nocode-instance-status--stash": {
144
- textColor: "#F77E4A",
145
- background: "rgba(247,126,74,0.1)",
146
- iconBackground: "#FFC837",
147
- placeholder: $t("sys.edhr.formInsStatusEnum.STASH")
148
- },
149
- "gct-nocode-instance-status--partial-submit": {
150
- textColor: "#FFAA00",
151
- background: "rgba(255,170,0,0.1)",
152
- iconBackground: "#FFD666",
153
- placeholder: $t("sys.appDesigner.approval.button.PartialSubmit")
154
- },
155
- "gct-nocode-instance-status--finish": {
156
- textColor: "#309C41",
157
- background: "rgba(48,156,65,0.1)",
158
- iconBackground: "#76DA57",
159
- placeholder: $t("sys.bpmn.flowNodeInstStatus.COMPLETED")
160
- },
161
- "gct-nocode-instance-status--abnormal": {
162
- textColor: "#F54547",
163
- background: " rgba(245,69,71,0.1)",
164
- iconBackground: "#FF6776",
165
- placeholder: $t("sys.bpmn.flowNodeInstStatus.EXCEPTION")
166
- },
167
- "gct-nocode-instance-status--not-filled": {
168
- textColor: "#6D82B0",
169
- background: "#E6EEFF",
170
- iconBackground: "#B4C8F4",
171
- placeholder: $t("sys.edhr.instanceStatus2DhrEnum.UNFILLED")
172
- },
173
- "gct-nocode-instance-status--running": {
174
- textColor: "#13C2C2",
175
- background: "rgba(19,194,194,0.1)",
176
- iconBackground: "#13C2C2",
177
- placeholder: $t("sys.bpmn.bizNodeInstStatus.running")
178
- },
179
- "gct-nocode-instance-status--already-filled": {
180
- textColor: "#026AC8",
181
- background: " rgba(2,106,200,0.1)",
182
- iconBackground: "#026AC8",
183
- placeholder: $t("sys.edhr.instanceStatus2DhrEnum.FILLED")
184
- },
185
- "gct-nocode-instance-status--invalid": {
186
- textColor: "#737A87",
187
- background: "#E5E5E5",
188
- iconBackground: "#C3C3C3",
189
- placeholder: $t("sys.edhr.dhrLogType.ABANDON")
190
- },
191
- "gct-nocode-instance-status--archived": {
192
- textColor: "#dda200",
193
- background: "#faf3df",
194
- iconBackground: "#dda200",
195
- placeholder: $t("sys.edhr.recordBook.archived")
196
- },
197
- "gct-nocode-instance-status--tmpl": {
198
- textColor: "#742fb2",
199
- background: "#f9f2ff",
200
- iconBackground: "#742fb2",
201
- placeholder: $t("sys.appDesigner.template")
202
- },
203
- "gct-nocode-instance-status--in-audit": {
204
- textColor: "#FF52C5",
205
- background: "rgba(255,82,197, 0.1)",
206
- iconBackground: "#FF52C5",
207
- placeholder: $t("sys.edhr.instanceStatus2FormEnum.IN_AUDIT")
208
- }
209
- };
210
- }
211
- };
212
- function useOnlineFormActionButton() {
213
- const baseBtn = [
214
- {
215
- type: "Cancel",
216
- customTitle: $t("sys.cancelText"),
217
- title: $t("sys.cancelText"),
218
- enable: 1,
219
- buttonType: "builtin",
220
- isCustom: false
221
- }
222
- ];
223
- const processFormBtnGroup = [
224
- {
225
- type: ButtonTypeEnum.Return,
226
- title: $t("sys.appDesigner.approval.button.Return"),
227
- api: api.apaas.onlineForm.postProcessReturn
228
- },
229
- {
230
- type: ButtonTypeEnum.Reassign,
231
- title: $t("sys.appDesigner.approval.button.Reassign"),
232
- style: {
233
- type: "primary"
234
- },
235
- api: api.apaas.onlineForm.postProcessReassign
236
- },
237
- {
238
- type: ButtonTypeEnum.Save,
239
- title: $t("sys.saveText"),
240
- style: {
241
- type: "primary"
242
- },
243
- api: api.apaas.onlineForm.postProcessSave
244
- },
245
- {
246
- type: ButtonTypeEnum.PartialSubmit,
247
- title: $t("sys.appDesigner.approval.button.PartialSubmit"),
248
- style: {
249
- type: "primary"
250
- },
251
- api: api.apaas.onlineForm.postProcessPartialSubmit
252
- },
253
- {
254
- type: ButtonTypeEnum.Submit,
255
- title: $t("sys.submit"),
256
- style: {
257
- type: "primary"
258
- },
259
- api: api.apaas.onlineForm.postProcessSubmit
260
- },
261
- {
262
- type: ButtonTypeEnum.Approve,
263
- title: $t("sys.appDesigner.approval.button.Approve"),
264
- style: {
265
- type: "primary"
266
- },
267
- api: api.apaas.onlineForm.postProcessApprove
268
- },
269
- {
270
- type: ButtonTypeEnum.Qualified,
271
- title: $t("sys.appDesigner.approval.button.Qualified"),
272
- api: api.apaas.onlineForm.postProcessApproveQualification
273
- },
274
- {
275
- type: ButtonTypeEnum.Unqualified,
276
- title: $t("sys.appDesigner.approval.button.Unqualified"),
277
- api: api.apaas.onlineForm.postProcessApprove
278
- }
279
- ];
280
- const formChangeBtnGroup = [
281
- {
282
- type: ButtonTypeEnum.Return,
283
- title: $t("sys.appDesigner.approval.button.Return"),
284
- api: api.apaas.form.postChangeProcessReturn,
285
- medproApi: window.NocodeAdapter.apis?.postMedproFormChangeProcessReturn
286
- },
287
- {
288
- type: ButtonTypeEnum.Reassign,
289
- title: $t("sys.appDesigner.approval.button.Reassign"),
290
- style: {
291
- type: "primary"
292
- },
293
- api: api.apaas.form.postChangeProcessReassign,
294
- medproApi: window.NocodeAdapter.apis?.postMedproFormChangeProcessReassign
295
- },
296
- {
297
- type: ButtonTypeEnum.Approve,
298
- title: $t("sys.appDesigner.approval.button.Approve"),
299
- style: {
300
- type: "primary"
301
- },
302
- api: api.apaas.form.postChangeProcessApprove,
303
- medproApi: window.NocodeAdapter.apis?.postMedproFormChangeProcessApprove
304
- }
305
- ];
306
- function renderActionButton(showButtons, buttonConfig, options) {
307
- const { formType, inDrawer, isViewPage, isRecordFill, processOperation } = options || {};
308
- const _baseBtn = inDrawer && !isViewPage ? baseBtn.slice() : [];
309
- if (!formType || formType === FormTypeEnum.TEXT || formType === FormTypeEnum.VIEW) {
310
- return [];
311
- }
312
- if (options.isFormChangeApprovalPage) {
313
- const buttonMap = safeParseArray(buttonConfig).reduce((acc, current) => {
314
- acc[current.type] = current;
315
- return acc;
316
- }, {});
317
- return formChangeBtnGroup.filter((info) => showButtons.includes(info.type)).map((item) => {
318
- const btn = buttonMap?.[item.type];
319
- if (btn && btn.enable) {
320
- return {
321
- ...btn,
322
- style: {
323
- ...item.style,
324
- ...btn.style
325
- },
326
- buttonType: "builtin",
327
- customTitle: btn.alias || item.title || $t("sys.pageDesigner.button"),
328
- belongFormChangeApproval: true,
329
- api: options.isMedPro ? item.medproApi : item.api
330
- };
331
- }
332
- }).filter((i) => i);
333
- }
334
- if (formType === FormTypeEnum.BASE || formType === FormTypeEnum.FILE) {
335
- if (options.modeType === RenderModeEnum.ViewMode) {
336
- return [];
337
- }
338
- return _baseBtn.concat(
339
- mergeByMultiKey(safeParseArray(buttonConfig), safeParseArray(processOperation), {
340
- keyFields: ["type", "buttonType"]
341
- }).filter((btn) => {
342
- return Boolean(btn.enable) && (!isRecordFill || btn.buttonType === "builtin" && (btn.type === ButtonTypeEnum.Save || btn.type === ButtonTypeEnum.Submit));
343
- }).map((btn) => {
344
- const isSaveOrSubmit = btn.buttonType === "builtin" && [ButtonTypeEnum.Submit, ButtonTypeEnum.Save, ButtonTypeEnum.PartialSubmit].includes(
345
- btn.type
346
- );
347
- return {
348
- ...btn,
349
- ...isSaveOrSubmit && {
350
- style: {
351
- type: "primary",
352
- ...btn.style
353
- }
354
- },
355
- customTitle: btn.alias || btn.title || $t("sys.pageDesigner.button"),
356
- signatureType: btn.signatureType || BpmnSignatureTypeEnum.None,
357
- api: btn.type === ButtonTypeEnum.PartialSubmit ? api.apaas.onlineForm.postPartialSubmit : btn.type === ButtonTypeEnum.Save ? api.apaas.onlineForm.postStash : api.apaas.onlineForm.postBaseSubmit
358
- };
359
- }).sort((a, b) => a.buttonType === b.buttonType ? 0 : a.buttonType === "custom" ? 1 : -1)
360
- );
361
- }
362
- if (formType === FormTypeEnum.PROCESS && options.bpmnType !== BpmnNodeTypeEnum.BpmnEnd) {
363
- if (isViewPage || options.modeType === RenderModeEnum.ViewMode) {
364
- return [];
365
- }
366
- const mergedBtns = mergeByMultiKey(
367
- safeParseArray(buttonConfig),
368
- safeParseArray(processOperation)
369
- );
370
- const custonBuiltinBtns = mergedBtns.filter((e) => e.isCustomBuiltin);
371
- const buttonMap = mergedBtns.reduce((acc, current) => {
372
- acc[current.type] = current;
373
- return acc;
374
- }, {});
375
- const customButton = Object.values(buttonMap).filter(
376
- (btn) => btn.enable && has(btn, "isCustom") && btn.isCustom && showButtons.includes(btn.type)
377
- ).map((item) => {
378
- const btn = buttonMap?.[item.type];
379
- return {
380
- ...btn,
381
- buttonType: "custom",
382
- customTitle: btn.alias || item.title || $t("sys.pageDesigner.button"),
383
- api: api.apaas.onlineForm.postProcessJump
384
- };
385
- });
386
- return _baseBtn.concat(customButton).concat(
387
- // 流程表单内置按钮
388
- processFormBtnGroup.filter((info) => showButtons.includes(info.type)).map((item) => {
389
- const btn = buttonMap?.[item.type];
390
- if (btn && btn.enable && !btn.isCustom) {
391
- return {
392
- ...btn,
393
- style: {
394
- ...item.style,
395
- ...btn.style
396
- },
397
- buttonType: "builtin",
398
- customTitle: btn.alias || item.title || $t("sys.pageDesigner.button"),
399
- api: item.api
400
- };
401
- }
402
- }).filter((i) => i)
403
- ).concat(
404
- custonBuiltinBtns.filter((e) => showButtons.includes(e.type)).map((e) => {
405
- const btn = buttonMap?.[e.type];
406
- const processBtn = processFormBtnGroup.find((f) => f.type === e.sourceType) || {};
407
- if (btn && btn.enable && btn.isCustomBuiltin) {
408
- return {
409
- ...btn,
410
- style: {
411
- ...processBtn.style,
412
- ...btn.style
413
- },
414
- buttonType: "builtin",
415
- cusBuiltinType: btn.type,
416
- type: btn.sourceType,
417
- customTitle: btn.alias || processBtn.title || $t("sys.pageDesigner.button"),
418
- api: processBtn.api
419
- };
420
- }
421
- }).filter((i) => i)
422
- );
423
- }
424
- return _baseBtn;
425
- }
426
- const autoSaveButtonMap = {
427
- [FormTypeEnum.BASE]: {
428
- type: ButtonTypeEnum.Save,
429
- title: $t("sys.saveText"),
430
- customTitle: $t("sys.saveText"),
431
- buttonType: "builtin",
432
- api: api.apaas.onlineForm.postStash
433
- },
434
- [FormTypeEnum.PROCESS]: {
435
- type: ButtonTypeEnum.Save,
436
- title: $t("sys.saveText"),
437
- customTitle: $t("sys.saveText"),
438
- buttonType: "builtin",
439
- api: api.apaas.onlineForm.postProcessSave
440
- }
441
- };
442
- return {
443
- renderActionButton,
444
- autoSaveButtonMap
445
- };
446
- }
447
- const useOnlineFormTransformField2Component = (fieldType) => {
448
- return {
449
- [FIELD_TYPE.TEXT]: {
450
- cmpKey: ComponentTypeEnum.Input
451
- },
452
- [FIELD_TYPE.LONG_TEXT]: {
453
- cmpKey: ComponentTypeEnum.Textarea
454
- },
455
- [FIELD_TYPE.INTEGER]: {
456
- cmpKey: ComponentTypeEnum.Inputnumber
457
- },
458
- [FIELD_TYPE.LONG]: {
459
- cmpKey: ComponentTypeEnum.Inputnumber
460
- },
461
- [FIELD_TYPE.DOUBLE]: {
462
- cmpKey: ComponentTypeEnum.InputDouble
463
- },
464
- [FIELD_TYPE.DECIMAL]: {
465
- cmpKey: ComponentTypeEnum.Inputnumber
466
- },
467
- [FIELD_TYPE.BOOLEAN]: {
468
- cmpKey: ComponentTypeEnum.Switch
469
- },
470
- [FIELD_TYPE.SERIAL]: {
471
- cmpKey: ComponentTypeEnum.Input
472
- },
473
- [FIELD_TYPE.IMAGE]: {
474
- cmpKey: ComponentTypeEnum.UploadImage
475
- },
476
- [FIELD_TYPE.SIGNATURE]: {
477
- cmpKey: ComponentTypeEnum.Sign
478
- },
479
- [FIELD_TYPE.ATTACHMENT]: {
480
- cmpKey: ComponentTypeEnum.UploadFile
481
- },
482
- [FIELD_TYPE.USER]: {
483
- cmpKey: ComponentTypeEnum.Userpicker
484
- },
485
- [FIELD_TYPE.USER_MULTI]: {
486
- cmpKey: ComponentTypeEnum.Userpicker
487
- },
488
- [FIELD_TYPE.ORG]: {
489
- cmpKey: ComponentTypeEnum.Department
490
- },
491
- [FIELD_TYPE.ORG_MULTI]: {
492
- cmpKey: ComponentTypeEnum.Department
493
- },
494
- [FIELD_TYPE.ENUM]: {
495
- cmpKey: ComponentTypeEnum.EnumSelect
496
- },
497
- [FIELD_TYPE.ENUM_MULTI]: {
498
- cmpKey: ComponentTypeEnum.EnumSelect
499
- },
500
- [FIELD_TYPE.OPTION]: {
501
- cmpKey: ComponentTypeEnum.EnumSelect
502
- },
503
- [FIELD_TYPE.OPTION_MULTI]: {
504
- cmpKey: ComponentTypeEnum.EnumSelect
505
- },
506
- [FIELD_TYPE.REF]: {
507
- cmpKey: ComponentTypeEnum.Select
508
- },
509
- [FIELD_TYPE.REF_MULTI]: {
510
- cmpKey: ComponentTypeEnum.Select
511
- },
512
- [FIELD_TYPE.MODEL_RELATION]: {
513
- cmpKey: ComponentTypeEnum.Select
514
- },
515
- [FIELD_TYPE.WAREHOUSE]: {
516
- cmpKey: ComponentTypeEnum.Select
517
- },
518
- [FIELD_TYPE.LOCATION]: {
519
- cmpKey: ComponentTypeEnum.Select
520
- },
521
- [FIELD_TYPE.DATE]: {
522
- cmpKey: ComponentTypeEnum.Datepicker
523
- },
524
- [FIELD_TYPE.DATE_TIME]: {
525
- cmpKey: ComponentTypeEnum.DateTimepicker
526
- },
527
- [FIELD_TYPE.TIME]: {
528
- cmpKey: ComponentTypeEnum.Timepicker
529
- },
530
- [FIELD_TYPE.EXPRESSION]: {
531
- cmpKey: ComponentTypeEnum.EXPRESSION
532
- },
533
- [FIELD_TYPE.AGG]: {
534
- cmpKey: ComponentTypeEnum.AGG
535
- },
536
- [FIELD_TYPE.MATERIAL_NO]: {
537
- cmpKey: ComponentTypeEnum.Trace
538
- },
539
- [FIELD_TYPE.STERILIZE_LOT]: {
540
- cmpKey: ComponentTypeEnum.Trace
541
- },
542
- [FIELD_TYPE.MATERIAL_LOT]: {
543
- cmpKey: ComponentTypeEnum.Trace
544
- },
545
- [FIELD_TYPE.RELATED_LOT_NO]: {
546
- cmpKey: ComponentTypeEnum.Trace
547
- },
548
- [FIELD_TYPE.PRODUCT]: {
549
- cmpKey: ComponentTypeEnum.Trace
550
- },
551
- [FIELD_TYPE.DEVICE]: {
552
- cmpKey: ComponentTypeEnum.Trace
553
- },
554
- [FIELD_TYPE.MFG_ORDER]: {
555
- cmpKey: ComponentTypeEnum.Trace
556
- },
557
- [FIELD_TYPE.RECORD_NO]: {
558
- cmpKey: ComponentTypeEnum.Trace
559
- },
560
- [FIELD_TYPE.TRACE_DATE]: {
561
- cmpKey: ComponentTypeEnum.Trace
562
- },
563
- [FIELD_TYPE.ORDER_NO]: {
564
- cmpKey: ComponentTypeEnum.Trace
565
- },
566
- [FIELD_TYPE.EXTERNAL_REF_NO]: {
567
- cmpKey: ComponentTypeEnum.Trace
568
- },
569
- [FIELD_TYPE.SHOPFLOOR]: {
570
- cmpKey: ComponentTypeEnum.Trace
571
- },
572
- [FIELD_TYPE.ROUTING_OPERATION]: {
573
- cmpKey: ComponentTypeEnum.Select
574
- },
575
- [FIELD_TYPE.GOOD_QTY]: {
576
- cmpKey: ComponentTypeEnum.InputDouble
577
- },
578
- [FIELD_TYPE.NOT_GOOD_QTY]: {
579
- cmpKey: ComponentTypeEnum.InputDouble
580
- },
581
- [FIELD_TYPE.REPORT_START_TIME]: {
582
- cmpKey: ComponentTypeEnum.DateTimepicker
583
- },
584
- [FIELD_TYPE.REPORT_END_TIME]: {
585
- cmpKey: ComponentTypeEnum.DateTimepicker
586
- },
587
- [FIELD_TYPE.WORK_HOURS]: {
588
- cmpKey: ComponentTypeEnum.Inputnumber
589
- },
590
- [FIELD_TYPE.PRODUCTION_DATE]: {
591
- cmpKey: ComponentTypeEnum.Datepicker
592
- },
593
- [FIELD_TYPE.REPORTER]: {
594
- cmpKey: ComponentTypeEnum.Sign
595
- },
596
- [FIELD_TYPE.NOT_GOOD_REASON]: {
597
- cmpKey: ComponentTypeEnum.Select
598
- },
599
- [FIELD_TYPE.NOT_GOOD_GROUP]: {
600
- cmpKey: ComponentTypeEnum.Select
601
- },
602
- [FIELD_TYPE.SCRAP_REASON]: {
603
- cmpKey: ComponentTypeEnum.Select
604
- },
605
- [FIELD_TYPE.SCRAP_GROUP]: {
606
- cmpKey: ComponentTypeEnum.Select
607
- },
608
- [FIELD_TYPE.SCRAP_QTY]: {
609
- cmpKey: ComponentTypeEnum.InputDouble
610
- },
611
- [FIELD_TYPE.SCRAP_MATERIAL]: {
612
- cmpKey: ComponentTypeEnum.Trace
613
- },
614
- [FIELD_TYPE.SCRAP_MATERIAL_NO]: {
615
- cmpKey: ComponentTypeEnum.Trace
616
- },
617
- [FIELD_TYPE.DESTRUCTIVE_TEST_QTY]: {
618
- cmpKey: ComponentTypeEnum.InputDouble
619
- },
620
- [FIELD_TYPE.PRODUCT_CHECK_QTY]: {
621
- cmpKey: ComponentTypeEnum.InputDouble
622
- },
623
- [FIELD_TYPE.MATERIAL_CHECK_QTY]: {
624
- cmpKey: ComponentTypeEnum.InputDouble
625
- },
626
- [FIELD_TYPE.QTY_REQUIRED]: {
627
- cmpKey: ComponentTypeEnum.InputDouble
628
- },
629
- [FIELD_TYPE.QTY_CONSUMED]: {
630
- cmpKey: ComponentTypeEnum.InputDouble
631
- },
632
- [FIELD_TYPE.QTY]: {
633
- cmpKey: ComponentTypeEnum.InputDouble
634
- },
635
- [FIELD_TYPE.DEVICE_REF]: {
636
- cmpKey: ComponentTypeEnum.Select
637
- },
638
- [FIELD_TYPE.DEVICE_REF_MULTI]: {
639
- cmpKey: ComponentTypeEnum.Select
640
- },
641
- [FIELD_TYPE.WAREHOUSE_RECEIPT_NO]: {
642
- cmpKey: ComponentTypeEnum.Input
643
- },
644
- [FIELD_TYPE.WAREHOUSE_RECEIPT_DATE]: {
645
- cmpKey: ComponentTypeEnum.Datepicker
646
- },
647
- [FIELD_TYPE.WAREHOUSE_MANAGER]: {
648
- cmpKey: ComponentTypeEnum.Sign
649
- },
650
- [FIELD_TYPE.OF_INST_NUM]: {
651
- cmpKey: ComponentTypeEnum.Inputnumber
652
- },
653
- [FIELD_TYPE.E_SOP]: {
654
- cmpKey: ComponentTypeEnum.Trace
655
- }
656
- }[fieldType];
657
- };
658
77
  const constantRequiredStyles = {
659
- "--required-border-color": "rgb(255, 31, 31, 0.36)",
78
+ "--required-border-color": "#ffb0ae",
660
79
  "--required-border-hover-color": "rgb(255, 31, 31, 0.86)",
661
- "--required-background-color": "rgb(255, 31, 31, 0.04)"
80
+ "--required-background-color": "#fff7f7"
662
81
  };
663
82
  const resetRequiredStyles = {
664
- "--required-border-color": "#e9e9e9",
83
+ "--required-border-color": "#e0e3eb",
665
84
  "--required-border-hover-color": "var(--ant-primary-color)",
666
85
  "--required-background-color": "transparent"
667
86
  };
@@ -904,13 +323,13 @@ const validate = async (formData, paper, uniqueId) => {
904
323
  };
905
324
  };
906
325
  class BomEntryValidator {
907
- constructor(bomEntry, enableSequenceLoading, materialNoNum, historyData, mainMaterialNo, mcPattern) {
326
+ constructor(bomEntry, enableSequenceLoading, getMaterialNoNum, historyData, mainMaterialNo, noBomMode) {
908
327
  this.bomEntry = bomEntry;
909
328
  this.enableSequenceLoading = enableSequenceLoading;
910
- this.materialNoNum = materialNoNum;
329
+ this.getMaterialNoNum = getMaterialNoNum;
911
330
  this.historyData = historyData;
912
331
  this.mainMaterialNo = mainMaterialNo;
913
- this.mcPattern = mcPattern;
332
+ this.noBomMode = noBomMode;
914
333
  this.productIds.push(this.bomEntry.product_id_);
915
334
  this.productCodes[this.bomEntry.product_id_] = this.bomEntry.product_code_;
916
335
  if (this.bomEntry.substitute_material_enabled_ && this.bomEntry.substitute_material_entries_) {
@@ -920,26 +339,31 @@ class BomEntryValidator {
920
339
  });
921
340
  }
922
341
  this.hasConsumed = this.calcQtyConsumed(this.historyData);
923
- this.total = this.materialNoNum * this.bomEntry.qty_required_;
924
342
  }
925
343
  bomEntry;
926
344
  enableSequenceLoading;
927
- materialNoNum;
345
+ getMaterialNoNum;
928
346
  historyData;
929
347
  mainMaterialNo;
930
- mcPattern;
348
+ noBomMode;
931
349
  /** 该明细使用到的产品的id集合 */
932
350
  productIds = [];
933
351
  /** 物料和code的映射 */
934
352
  productCodes = {};
935
353
  /** 历史数据中已经消耗的 */
936
354
  hasConsumed = 0;
937
- /** 需求总量 */
938
- total = 0;
939
355
  /** 剩于可消耗数量 */
940
356
  get remainingNum() {
941
357
  return this.total - this.hasConsumed;
942
358
  }
359
+ /** 批次/生产数量(用时读取,避免构造快照过期) */
360
+ get materialNoNum() {
361
+ return Number(this.getMaterialNoNum()) || 0;
362
+ }
363
+ /** 需求总量 = 数量倍数 × BOM 单位用量 */
364
+ get total() {
365
+ return this.materialNoNum * this.bomEntry.qty_required_;
366
+ }
943
367
  /**
944
368
  * 翻译物料的code
945
369
  * @param productId
@@ -956,6 +380,38 @@ class BomEntryValidator {
956
380
  filterGroupData(arr) {
957
381
  return arr.filter((i) => this.productIds.includes(i.product_id_));
958
382
  }
383
+ /** 行是否属于本 BOM 组(优先 bom_entry_id_,避免跨组 product_id_ 误判) */
384
+ isRowInGroup(row) {
385
+ if (row.deleted_) return false;
386
+ if (row.bom_entry_id_) return row.bom_entry_id_ === this.bomEntry.id_;
387
+ if (row.product_id_) return this.productIds.includes(row.product_id_);
388
+ return false;
389
+ }
390
+ /** 组内已选中的物料(整批替代;不排除当前行) */
391
+ getGroupExistingProductId(tableData) {
392
+ for (const row of tableData) {
393
+ if (row.deleted_) continue;
394
+ if (!this.isRowInGroup(row)) continue;
395
+ if (row.product_id_) return row.product_id_;
396
+ }
397
+ return void 0;
398
+ }
399
+ /**
400
+ * 本组 product_id_ 下拉可选范围
401
+ * - 未开替代料:仅主料
402
+ * - 整批替代:组内已有 → 锁定该物料;否则主料+替代料
403
+ * - 混用等:主料+替代料
404
+ */
405
+ getSelectableProductIds(tableData) {
406
+ if (!this.bomEntry.substitute_material_enabled_) {
407
+ return [this.bomEntry.product_id_];
408
+ }
409
+ if (this.bomEntry.substitute_policy_ === "only_one") {
410
+ const existing = this.getGroupExistingProductId(tableData);
411
+ if (existing) return [existing];
412
+ }
413
+ return this.productIds;
414
+ }
959
415
  validateSubstitute(arr) {
960
416
  const groupData = this.filterGroupData(arr);
961
417
  if (!this.bomEntry.substitute_material_enabled_) {
@@ -966,7 +422,7 @@ class BomEntryValidator {
966
422
  } else if (this.bomEntry.substitute_policy_ === "only_one") {
967
423
  const idSet = new Set(groupData.map((i) => i.product_id_));
968
424
  if (idSet.size > 1) {
969
- throw new Error($t("sys.edhr.mcTable.notAllowMixSubstituteMaterial"));
425
+ throw new Error($t("整批替代,不允许混用"));
970
426
  }
971
427
  }
972
428
  }
@@ -995,6 +451,64 @@ class BomEntryValidator {
995
451
  throw new Error(errorMsg);
996
452
  }
997
453
  }
454
+ /**
455
+ * 通用校验 3(带即将写入的行):组内已有行 + row 的批次去重后,是否超过混批次数。
456
+ * - 非按批次 / 未开混批校验 / row 不属于本组 → 直接通过
457
+ * - 排除空物料;空批次不计入
458
+ */
459
+ validateLotMixingWithRow(row, arr) {
460
+ if (this.bomEntry.type_ !== "by_lot") {
461
+ return;
462
+ }
463
+ if (!this.bomEntry.lot_mixing_enabled_) {
464
+ return;
465
+ }
466
+ if (!row.product_id_ || !this.productIds.includes(row.product_id_)) {
467
+ return;
468
+ }
469
+ const lots = /* @__PURE__ */ new Set();
470
+ this.filterGroupData(arr).forEach((i) => {
471
+ if (i.product_id_ && i.material_no_) {
472
+ lots.add(i.material_no_);
473
+ }
474
+ });
475
+ if (row.material_no_) {
476
+ lots.add(row.material_no_);
477
+ }
478
+ const maxTimes = this.bomEntry.lot_mixing_times_;
479
+ if (lots.size > maxTimes) {
480
+ throw new Error(`超过允许的混批次数:${maxTimes}`);
481
+ }
482
+ }
483
+ /** 指定物料批次:material_no_ 须在 specified_material_entries_ 的 name_ 范围内 */
484
+ validateSpecifiedMaterialNo(row) {
485
+ if (!this.bomEntry.specified_material_no_enabled_) {
486
+ return;
487
+ }
488
+ if (this.bomEntry.type_ === "view") {
489
+ return;
490
+ }
491
+ const lot = row.material_no_;
492
+ if (!lot) {
493
+ return;
494
+ }
495
+ const allowed = (this.bomEntry.specified_material_entries_ ?? []).map((e) => e.name_).filter(Boolean);
496
+ if (!allowed.includes(lot)) {
497
+ throw new Error(`${lot},不在指定物料批次范围内`);
498
+ }
499
+ }
500
+ /** 整组指定批次校验:组内每一行有批次值的都检查 */
501
+ validateSpecifiedMaterialNoForGroup(arr) {
502
+ if (!this.bomEntry.specified_material_no_enabled_) {
503
+ return;
504
+ }
505
+ arr.forEach((row) => {
506
+ if (row.deleted_ || !this.isRowInGroup(row) || !row.material_no_) {
507
+ return;
508
+ }
509
+ this.validateSpecifiedMaterialNo(row);
510
+ });
511
+ }
998
512
  /**
999
513
  * 校验数量
1000
514
  * @param arr
@@ -1073,6 +587,49 @@ class BomEntryValidator {
1073
587
  const min = await getValue(this.bomEntry.min_value_);
1074
588
  return { max, min };
1075
589
  }
590
+ /**
591
+ * 通用校验 5:本组上料数量是否满足 qty_validation_rule_。
592
+ * 前置假设:必填、替代料、混批等已由调用方完成。
593
+ * @param sequential 是否按顺序上料;eq 规则在非顺序模式下允许少上
594
+ */
595
+ async validateGroupQty(arr, sequential = this.enableSequenceLoading, groupNo) {
596
+ const entry = this.bomEntry;
597
+ if (!entry.qty_validation_enabled_ || entry.type_ === "view") {
598
+ return;
599
+ }
600
+ const loaded = this.calcQtyConsumed(arr);
601
+ const required = this.remainingNum;
602
+ const diff = loaded - required;
603
+ const rule = entry.qty_validation_rule_;
604
+ const fail = (msg) => {
605
+ const prefix = groupNo != null && groupNo > 0 ? $t("sys.groupQtyErrorPrefix", { groupNo }) : "";
606
+ throw new Error(`${prefix}${msg}`);
607
+ };
608
+ switch (rule) {
609
+ case "eq":
610
+ if (sequential) {
611
+ if (diff !== 0) fail($t("sys.qtyValidationRule.eq"));
612
+ } else {
613
+ if (loaded > required) fail($t("sys.qtyValidationRule.lte"));
614
+ }
615
+ break;
616
+ case "gte":
617
+ if (diff < 0) fail($t("sys.qtyValidationRule.gte"));
618
+ break;
619
+ case "lte":
620
+ if (diff > 0) fail($t("sys.qtyValidationRule.lte"));
621
+ break;
622
+ case "bounds": {
623
+ const groupData = this.filterGroupData(arr);
624
+ const consumeSum = loaded + this.hasConsumed;
625
+ const { min, max } = await this.calcCustomNumberLimit(groupData[0]);
626
+ if (min !== void 0 && consumeSum < min || max !== void 0 && consumeSum > max) {
627
+ fail($t("sys.qtyValidationRule.bounds", { min, max }));
628
+ }
629
+ break;
630
+ }
631
+ }
632
+ }
1076
633
  /**
1077
634
  * 按顺序投料用
1078
635
  * 检查数据中的当前明细的填报是否已经完成
@@ -1126,31 +683,35 @@ class BomEntryValidator {
1126
683
  }
1127
684
  }
1128
685
  class BomEntriesValidator {
1129
- constructor(entries, enableSequenceLoading, materialNoNum, historyData, mainMaterialNo, mcPattern) {
686
+ constructor(entries, enableSequenceLoading, getMaterialNoNum, historyData, mainMaterialNo, noBomMode) {
1130
687
  this.entries = entries;
1131
688
  this.enableSequenceLoading = enableSequenceLoading;
1132
- this.materialNoNum = materialNoNum;
689
+ this.getMaterialNoNum = getMaterialNoNum;
1133
690
  this.historyData = historyData;
1134
691
  this.mainMaterialNo = mainMaterialNo;
1135
- this.mcPattern = mcPattern;
692
+ this.noBomMode = noBomMode;
1136
693
  this.bomEntryValidators = entries.map(
1137
694
  (i) => new BomEntryValidator(
1138
695
  i,
1139
696
  enableSequenceLoading,
1140
- materialNoNum,
697
+ getMaterialNoNum,
1141
698
  historyData,
1142
699
  mainMaterialNo,
1143
- mcPattern
700
+ noBomMode
1144
701
  )
1145
702
  );
1146
703
  }
1147
704
  entries;
1148
705
  enableSequenceLoading;
1149
- materialNoNum;
706
+ getMaterialNoNum;
1150
707
  historyData;
1151
708
  mainMaterialNo;
1152
- mcPattern;
709
+ noBomMode;
1153
710
  bomEntryValidators;
711
+ /** 当前批次/生产数量 */
712
+ get materialNoNum() {
713
+ return Number(this.getMaterialNoNum()) || 0;
714
+ }
1154
715
  /**
1155
716
  * 翻译物料的code
1156
717
  * @param productId
@@ -1173,6 +734,119 @@ class BomEntriesValidator {
1173
734
  findUtilByProductId(productId) {
1174
735
  return this.bomEntryValidators.find((i) => i.productIds.includes(productId));
1175
736
  }
737
+ /** 编辑行所属组 id;空物料且无 bom_entry_id_ 时返回 null */
738
+ getRowGroupId(row) {
739
+ if (row.bom_entry_id_) return row.bom_entry_id_;
740
+ if (row.product_id_) {
741
+ const util = this.findUtilByProductId(row.product_id_);
742
+ return util?.bomEntry.id_ ?? null;
743
+ }
744
+ return null;
745
+ }
746
+ /**
747
+ * 是否有正在编辑的组。
748
+ * 一组可多行同时 !is_confirmed_;正常应只有一组。
749
+ * @returns 有编辑行且只落在一组 → true;无编辑行 → false;跨多组编辑 → 抛错
750
+ */
751
+ hasEditingGroup(arr) {
752
+ const editRows = arr.filter((i) => !i.is_confirmed_ && !i.deleted_);
753
+ if (!editRows.length) return false;
754
+ const groupIds = /* @__PURE__ */ new Set();
755
+ for (const row of editRows) {
756
+ const id = this.getRowGroupId(row);
757
+ if (id) groupIds.add(id);
758
+ }
759
+ if (groupIds.size === 0) return true;
760
+ if (groupIds.size > 1) {
761
+ throw new Error("同时只能有一组处于编辑态");
762
+ }
763
+ return true;
764
+ }
765
+ /** 取当前唯一编辑组的 BOM 明细 id;没有则 undefined */
766
+ getEditingGroupId(arr) {
767
+ if (!this.hasEditingGroup(arr)) return;
768
+ const editRows = arr.filter((i) => !i.is_confirmed_ && !i.deleted_);
769
+ for (const row of editRows) {
770
+ const id = this.getRowGroupId(row);
771
+ if (id) return id;
772
+ }
773
+ }
774
+ /**
775
+ * 行 → BOM 明细在 bomEntryValidators 中的下标,找不到返回 -1
776
+ */
777
+ resolveEntryIndex(row) {
778
+ if (row.product_id_) {
779
+ const i = this.bomEntryValidators.findIndex((v) => v.productIds.includes(row.product_id_));
780
+ if (i >= 0) return i;
781
+ }
782
+ return row.bom_entry_id_ ? this.bomEntryValidators.findIndex((v) => v.bomEntry.id_ === row.bom_entry_id_) : -1;
783
+ }
784
+ /**
785
+ * 行所属组在序号列中的 groupOrderIndex(0-based;-1 未绑 BOM 组)
786
+ * 与 material-consume-table 序号列逻辑一致
787
+ */
788
+ resolveGroupOrderIndex(row, arr) {
789
+ const entryIdx = this.resolveEntryIndex(row);
790
+ if (this.enableSequenceLoading) {
791
+ return entryIdx;
792
+ }
793
+ if (entryIdx < 0) {
794
+ return -1;
795
+ }
796
+ return this.resolveEntryOrderInTable(entryIdx, arr);
797
+ }
798
+ /** 已知 BomEntryValidator 时算 groupOrderIndex */
799
+ resolveGroupOrderIndexByUtil(util, arr) {
800
+ return this.resolveGroupOrderIndex(
801
+ { bom_entry_id_: util.bomEntry.id_ },
802
+ arr
803
+ );
804
+ }
805
+ /** 非顺序上料:BOM 组在表中首次出现的顺序(0-based) */
806
+ resolveEntryOrderInTable(entryIdx, arr) {
807
+ const seen = [];
808
+ for (const r of arr) {
809
+ if (r.deleted_) continue;
810
+ const idx = this.resolveEntryIndex(r);
811
+ if (idx < 0 || seen.includes(idx)) continue;
812
+ seen.push(idx);
813
+ }
814
+ return seen.indexOf(entryIdx);
815
+ }
816
+ /**
817
+ * 定位顺序上料时的当前编辑组对应 BOM 明细。
818
+ * 编辑行无物料时,用前后组夹出范围,取 (prev, next) 开区间起点。
819
+ */
820
+ findSequenceBomEntry(arr) {
821
+ const editRows = arr.filter((i) => !i.is_confirmed_ && !i.deleted_);
822
+ if (!editRows.length) return;
823
+ const hit = editRows.find((i) => i.product_id_) ?? editRows.find((i) => i.bom_entry_id_);
824
+ if (hit?.product_id_) return this.findUtilByProductId(hit.product_id_);
825
+ if (hit?.bom_entry_id_) {
826
+ return this.bomEntryValidators.find((v) => v.bomEntry.id_ === hit.bom_entry_id_);
827
+ }
828
+ const from = arr.indexOf(editRows[0]);
829
+ const to = arr.indexOf(editRows[editRows.length - 1]);
830
+ let prev = -1;
831
+ let next = this.bomEntryValidators.length;
832
+ for (let i = from - 1; i >= 0; i--) {
833
+ const idx = this.resolveEntryIndex(arr[i]);
834
+ if (idx >= 0) {
835
+ prev = idx;
836
+ break;
837
+ }
838
+ }
839
+ for (let i = to + 1; i < arr.length; i++) {
840
+ const idx = this.resolveEntryIndex(arr[i]);
841
+ if (idx >= 0) {
842
+ next = idx;
843
+ break;
844
+ }
845
+ }
846
+ const cur = prev + 1;
847
+ if (cur >= next || cur >= this.bomEntryValidators.length) return;
848
+ return this.bomEntryValidators[cur];
849
+ }
1176
850
  /**
1177
851
  * 检验是否符合顺序投料的顺序要求
1178
852
  * @param row 当前编辑的行
@@ -1183,21 +857,166 @@ class BomEntriesValidator {
1183
857
  if (!this.enableSequenceLoading) {
1184
858
  return;
1185
859
  }
1186
- const util = row ? this.findUtilByProductId(row.product_id_) : void 0;
1187
- for (const item of this.bomEntryValidators) {
1188
- if (item === util) {
1189
- break;
1190
- } else {
1191
- await item.validateHasCompleted(arr);
860
+ const seqBomEntry = this.findSequenceBomEntry(arr);
861
+ if (!seqBomEntry) throw new Error("没有查找到对应的上料顺序");
862
+ if (!seqBomEntry.productIds.includes(row.product_id_)) {
863
+ throw new Error($t("请按顺序上料"));
864
+ }
865
+ }
866
+ /** 表中是否已有该 BOM 组(有物料行或带 bom_entry_id_ 的空行) */
867
+ groupExistsInTable(arr, util) {
868
+ return arr.some((row) => isRowInBomGroup(row, util));
869
+ }
870
+ /**
871
+ * 按 BOM 顺序计算 target 组应插入的下标:
872
+ * 插到表中「第一个 BOM 下标更大的组」之前;没有则表末。
873
+ */
874
+ resolveBomOrderInsertIndex(arr, target) {
875
+ const targetIdx = this.bomEntryValidators.indexOf(target);
876
+ if (targetIdx < 0) return arr.length;
877
+ for (let i = 0; i < arr.length; i++) {
878
+ const row = arr[i];
879
+ if (row.deleted_) continue;
880
+ const idx = this.resolveEntryIndex(row);
881
+ if (idx > targetIdx) return i;
882
+ }
883
+ return arr.length;
884
+ }
885
+ /**
886
+ * 组装扫码填充计划:切组/建组标记 + 相对 arr 的下标。
887
+ * needInsert 时优先填 groupInsertIndex 占位行,勿再直接用 member/append 下标(会错位)。
888
+ */
889
+ buildScanFillPlan(arr, current, target) {
890
+ const memberIndexes = [];
891
+ const emptyProductIndexes = [];
892
+ const emptyLotIndexes = [];
893
+ const byLot = target.bomEntry.type_ === "by_lot";
894
+ let currentLast = -1;
895
+ arr.forEach((row, idx) => {
896
+ if (isRowInBomGroup(row, current)) currentLast = idx;
897
+ if (!isRowInBomGroup(row, target)) return;
898
+ if (!row.product_id_) {
899
+ emptyProductIndexes.push(idx);
900
+ return;
901
+ }
902
+ memberIndexes.push(idx);
903
+ if (byLot && !row.material_no_) emptyLotIndexes.push(idx);
904
+ });
905
+ const needInsert = !this.groupExistsInTable(arr, target);
906
+ const last2 = memberIndexes[memberIndexes.length - 1];
907
+ let groupInsertIndex = -1;
908
+ if (needInsert) {
909
+ groupInsertIndex = current !== target && currentLast >= 0 ? currentLast + 1 : this.resolveBomOrderInsertIndex(arr, target);
910
+ }
911
+ return {
912
+ target,
913
+ current,
914
+ needSwitch: current !== target,
915
+ needInsert,
916
+ groupInsertIndex,
917
+ memberIndexes,
918
+ emptyProductIndexes,
919
+ emptyLotIndexes,
920
+ appendIndex: last2 !== void 0 ? last2 + 1 : arr.length
921
+ };
922
+ }
923
+ /**
924
+ * 通用校验 2:物料是否允许写入目标组(不改动原 validateSubstitute)
925
+ */
926
+ assertGroupSubstitute(util, productId, arr) {
927
+ const entry = util.bomEntry;
928
+ if (entry.type_ === "view" || !entry.substitute_material_enabled_) {
929
+ if (productId !== entry.product_id_) {
930
+ throw new Error("匹配不到对应物料,请按规则上料或新增物料");
931
+ }
932
+ return;
933
+ }
934
+ if (!util.productIds.includes(productId)) {
935
+ throw new Error("匹配不到对应物料,请按规则上料或新增物料");
936
+ }
937
+ util.validateSubstitute([
938
+ ...arr,
939
+ { product_id_: productId, is_confirmed_: false, expiration_date_: "" }
940
+ ]);
941
+ }
942
+ /**
943
+ * 扫码定位目标组 + 通用校验 2,返回填充计划(切组/建组/下标)。
944
+ * 不改表数据。
945
+ */
946
+ validateSequenceScan(row, arr) {
947
+ const productId = row.product_id_;
948
+ const finish = (current2, target) => {
949
+ this.assertGroupSubstitute(target, productId, arr);
950
+ return this.buildScanFillPlan(arr, current2, target);
951
+ };
952
+ if (!this.enableSequenceLoading) {
953
+ const target = this.findUtilByProductId(productId);
954
+ if (!target) throw new Error("匹配不到对应物料,请按规则上料或新增物料");
955
+ return finish(target, target);
956
+ }
957
+ const current = this.findSequenceBomEntry(arr);
958
+ if (!current) {
959
+ const target = this.findUtilByProductId(productId);
960
+ if (!target) throw new Error("匹配不到对应物料,请按规则上料或新增物料");
961
+ if (this.groupExistsInTable(arr, target)) {
962
+ throw new Error("请勿重复上料");
963
+ }
964
+ return finish(target, target);
965
+ }
966
+ if (current.productIds.includes(productId)) return finish(current, current);
967
+ const currentIdx = this.bomEntryValidators.indexOf(current);
968
+ for (let i = 0; i < currentIdx; i++) {
969
+ const prev = this.bomEntryValidators[i];
970
+ if (!prev.productIds.includes(productId)) continue;
971
+ throw new Error(this.groupExistsInTable(arr, prev) ? "请勿重复上料" : $t("请按顺序上料"));
972
+ }
973
+ for (let i = currentIdx + 1; i < this.bomEntryValidators.length; i++) {
974
+ const next = this.bomEntryValidators[i];
975
+ const exists = this.groupExistsInTable(arr, next);
976
+ const optional = !next.bomEntry.force_loading_enabled_;
977
+ const hit = next.productIds.includes(productId);
978
+ if (optional && !exists) {
979
+ if (hit) return finish(current, next);
980
+ continue;
1192
981
  }
982
+ if (!hit) throw new Error($t("请按顺序上料"));
983
+ return finish(current, next);
1193
984
  }
985
+ throw new Error($t("请按顺序上料"));
986
+ }
987
+ /**
988
+ * 单组整组校验(提交编辑态组 / 切组前复用)
989
+ */
990
+ async validateGroup(arr, util) {
991
+ const rows = arr.filter(
992
+ (r) => !r.deleted_ && r.product_id_ && (util.productIds.includes(r.product_id_) || r.bom_entry_id_ === util.bomEntry.id_)
993
+ );
994
+ if (!rows.length) throw new Error($t("sys.edhr.mcTable.materialEmptyError"));
995
+ rows.forEach((row) => {
996
+ this.validateDataCompleted(row);
997
+ if (row.expiration_date_ && dayjs(row.expiration_date_).endOf("day").isBefore(dayjs())) {
998
+ throw new Error($t("sys.edhr.mcTable.expirationError"));
999
+ }
1000
+ });
1001
+ util.validateSubstitute(arr);
1002
+ util.validateLotMixing(arr);
1003
+ util.validateSpecifiedMaterialNoForGroup(arr);
1004
+ const orderIndex = this.resolveGroupOrderIndexByUtil(util, arr);
1005
+ const groupNo = orderIndex >= 0 ? orderIndex + 1 : void 0;
1006
+ await util.validateGroupQty(arr, this.enableSequenceLoading, groupNo);
1007
+ }
1008
+ /**
1009
+ * 切组前校验当前编辑组:BOM 内 + 必填、有效期、替代料、混批、数量校验
1010
+ */
1011
+ async validateCurrentGroupForSwitch(arr, current) {
1012
+ await this.validateGroup(arr, current);
1194
1013
  }
1195
1014
  /**
1196
1015
  * 校验物料是否在bom里被使用
1197
1016
  * @param row 单行的数据
1198
1017
  */
1199
1018
  validateInBom(row) {
1200
- if (this.mcPattern === MaterialConsumptionPatternEnum.RECORD) {
1019
+ if (this.noBomMode) {
1201
1020
  return;
1202
1021
  }
1203
1022
  if (!row.product_id_) {
@@ -1205,12 +1024,7 @@ class BomEntriesValidator {
1205
1024
  }
1206
1025
  const util = this.findUtilByProductId(row.product_id_);
1207
1026
  if (!util) {
1208
- const name = row.product_id__lb_ ? JSON.parse(row.product_id__lb_).join(",") : "";
1209
- throw new Error(
1210
- $t("sys.edhr.mcTable.productNotDefine", {
1211
- product: name
1212
- })
1213
- );
1027
+ throw new Error($t("匹配不到对应物料,请按规则上料或新增物料"));
1214
1028
  }
1215
1029
  }
1216
1030
  /**
@@ -1257,6 +1071,13 @@ class BomEntriesValidator {
1257
1071
  i.validateLotMixing(arr);
1258
1072
  });
1259
1073
  }
1074
+ /**
1075
+ * 通用校验 3(扫码/写入前):用 row + 表内同行组数据对比混批次数,不改动原 validateLotMixing
1076
+ */
1077
+ validateLotMixingWithRow(row, arr) {
1078
+ const util = this.findUtilByProductId(row.product_id_);
1079
+ util?.validateLotMixingWithRow(row, arr);
1080
+ }
1260
1081
  /**
1261
1082
  * 校验数量
1262
1083
  * @param arr
@@ -1293,15 +1114,26 @@ class BomEntriesValidator {
1293
1114
  }
1294
1115
  }
1295
1116
  /**
1296
- * 检查扫描数据是否可以插入
1117
+ * 检查扫描数据是否可以插入,通过后返回填充计划(记录模式无 plan)
1118
+ */
1119
+ async validateScanCanInsert(row, arr) {
1120
+ if (this.noBomMode) {
1121
+ return;
1122
+ }
1123
+ this.validateInBom(row);
1124
+ const plan = this.validateSequenceScan(row, arr);
1125
+ plan.target.validateSpecifiedMaterialNo(row);
1126
+ plan.target.validateLotMixingWithRow(row, arr);
1127
+ return plan;
1128
+ }
1129
+ /**
1130
+ * 校验当前编辑行的数据
1297
1131
  * @param arr
1132
+ * @returns
1298
1133
  */
1299
- async validateScanCanInsert(arr) {
1134
+ async validateEditRow(arr) {
1300
1135
  const editRow = arr.find((i) => !i.is_confirmed_);
1301
- if (!editRow) {
1302
- throw new Error($t("sys.edhr.mcTable.noEditingRow"));
1303
- }
1304
- if (this.mcPattern === MaterialConsumptionPatternEnum.RECORD) {
1136
+ if (!editRow || this.noBomMode) {
1305
1137
  return;
1306
1138
  }
1307
1139
  this.validateInBom(editRow);
@@ -1309,6 +1141,45 @@ class BomEntriesValidator {
1309
1141
  this.validateSubstitute(arr);
1310
1142
  this.validateLotMixing(arr);
1311
1143
  }
1144
+ /**
1145
+ * 顺序上料提交:表中最后一组之前,必须上料组不能缺失(仅结构/顺序,不校验数量)
1146
+ */
1147
+ assertSubmitSequenceOrder(arr) {
1148
+ const lastPresentIdx = this.bomEntryValidators.reduce(
1149
+ (max, util, i) => this.groupExistsInTable(arr, util) ? i : max,
1150
+ -1
1151
+ );
1152
+ if (lastPresentIdx < 0) {
1153
+ return;
1154
+ }
1155
+ for (let i = 0; i <= lastPresentIdx; i++) {
1156
+ const util = this.bomEntryValidators[i];
1157
+ if (util.bomEntry.force_loading_enabled_ && !this.groupExistsInTable(arr, util)) {
1158
+ throw new Error(`物料${util.bomEntry.product_code_}为必须上料,请完成该组上料`);
1159
+ }
1160
+ }
1161
+ }
1162
+ /**
1163
+ * 提交整表校验:必须上料组须存在;顺序上料校验组序;表中存在的组走整组校验(不含库存)
1164
+ */
1165
+ async validateAllRows(arr) {
1166
+ if (this.noBomMode) {
1167
+ return;
1168
+ }
1169
+ for (const util of this.bomEntryValidators) {
1170
+ if (util.bomEntry.force_loading_enabled_ && !this.groupExistsInTable(arr, util)) {
1171
+ throw new Error(`物料${util.bomEntry.product_code_}为必须上料,请完成该组上料`);
1172
+ }
1173
+ }
1174
+ if (this.enableSequenceLoading) {
1175
+ this.assertSubmitSequenceOrder(arr);
1176
+ }
1177
+ for (const util of this.bomEntryValidators) {
1178
+ if (this.groupExistsInTable(arr, util)) {
1179
+ await this.validateGroup(arr, util);
1180
+ }
1181
+ }
1182
+ }
1312
1183
  /**
1313
1184
  * 把扫描数据按情况插入到数组的位置,返回新数组
1314
1185
  * @param row
@@ -1360,7 +1231,317 @@ class BomEntriesValidator {
1360
1231
  return Array.from(result).map((i) => i.split(":").pop());
1361
1232
  }
1362
1233
  }
1363
- const calculate$1 = (...args) => window.NocodeAdapter.utils?.formulaCalculate?.(...args);
1234
+ function isRowInBomGroup(row, util) {
1235
+ return util.isRowInGroup(row);
1236
+ }
1237
+ function setGroupEditState(table, util, editing) {
1238
+ table.forEach((r) => {
1239
+ if (isRowInBomGroup(r, util)) {
1240
+ r.is_confirmed_ = !editing;
1241
+ }
1242
+ });
1243
+ }
1244
+ var ScanParamType = /* @__PURE__ */ ((ScanParamType2) => {
1245
+ ScanParamType2["Lot"] = "lot";
1246
+ ScanParamType2["UniqueCode"] = "uniqueCode";
1247
+ return ScanParamType2;
1248
+ })(ScanParamType || {});
1249
+ var RequiredQtyCalcRule = /* @__PURE__ */ ((RequiredQtyCalcRule2) => {
1250
+ RequiredQtyCalcRule2["LotQty"] = "lotQty";
1251
+ RequiredQtyCalcRule2["ProductQty"] = "productQty";
1252
+ return RequiredQtyCalcRule2;
1253
+ })(RequiredQtyCalcRule || {});
1254
+ async function applyScanFillPlan(arr, scanRow, plan, options) {
1255
+ const table = cloneDeep(arr);
1256
+ if (!plan) {
1257
+ fillNoBomRow(table, scanRow);
1258
+ return table;
1259
+ }
1260
+ if (plan.needSwitch) {
1261
+ await options?.validateCurrentGroupForSwitch?.(table, plan.current);
1262
+ }
1263
+ const fillAt = plan.needInsert ? insertEmptyGroupRow(table, plan) : void 0;
1264
+ if (plan.needSwitch) {
1265
+ applyGroupEditState(table, plan);
1266
+ }
1267
+ fillTargetGroup(table, scanRow, plan, fillAt);
1268
+ return table;
1269
+ }
1270
+ function writeScanFields(target, scanRow, bomEntryId) {
1271
+ const targetRec = target;
1272
+ const frontKey = targetRec[FRONT_ROW_KEY];
1273
+ const id_ = targetRec.id_;
1274
+ Object.assign(target, cloneDeep(scanRow));
1275
+ if (frontKey != null && String(frontKey).trim() !== "") {
1276
+ targetRec[FRONT_ROW_KEY] = frontKey;
1277
+ }
1278
+ if (id_ != null) {
1279
+ targetRec.id_ = id_;
1280
+ }
1281
+ if (bomEntryId) target.bom_entry_id_ = bomEntryId;
1282
+ target.is_confirmed_ = false;
1283
+ }
1284
+ function fillNoBomRow(table, scanRow) {
1285
+ const emptyIdx = table.findIndex((r) => !r.deleted_ && !r.product_id_);
1286
+ if (emptyIdx >= 0) {
1287
+ writeScanFields(table[emptyIdx], scanRow);
1288
+ return;
1289
+ }
1290
+ const row = { is_confirmed_: false, expiration_date_: "" };
1291
+ ensureFrontRowKey(row);
1292
+ writeScanFields(row, scanRow);
1293
+ table.push(row);
1294
+ }
1295
+ function insertEmptyGroupRow(table, plan) {
1296
+ const empty = {
1297
+ bom_entry_id_: plan.target.bomEntry.id_,
1298
+ is_confirmed_: false,
1299
+ expiration_date_: ""
1300
+ };
1301
+ ensureFrontRowKey(empty);
1302
+ table.splice(plan.groupInsertIndex, 0, empty);
1303
+ return plan.groupInsertIndex;
1304
+ }
1305
+ function applyGroupEditState(table, plan) {
1306
+ setGroupEditState(table, plan.current, false);
1307
+ setGroupEditState(table, plan.target, true);
1308
+ }
1309
+ function fillTargetGroup(table, scanRow, plan, fillAt) {
1310
+ const bomId = plan.target.bomEntry.id_;
1311
+ if (fillAt !== void 0) {
1312
+ writeScanFields(table[fillAt], scanRow, bomId);
1313
+ return;
1314
+ }
1315
+ if (plan.emptyProductIndexes.length) {
1316
+ writeScanFields(table[plan.emptyProductIndexes[0]], scanRow, bomId);
1317
+ return;
1318
+ }
1319
+ const action = resolveInGroupFill(scanRow, table, plan);
1320
+ if (action.type === "fill") {
1321
+ writeScanFields(table[action.index], scanRow, bomId);
1322
+ return;
1323
+ }
1324
+ const nr = { is_confirmed_: false, expiration_date_: "" };
1325
+ ensureFrontRowKey(nr);
1326
+ writeScanFields(nr, scanRow, bomId);
1327
+ table.splice(plan.appendIndex, 0, nr);
1328
+ }
1329
+ function resolveInGroupFill(scanRow, table, plan) {
1330
+ const { type_ } = plan.target.bomEntry;
1331
+ const sameIndexes = plan.memberIndexes.filter(
1332
+ (i) => table[i]?.product_id_ === scanRow.product_id_
1333
+ );
1334
+ if (sameIndexes.length) {
1335
+ if (type_ === "view") return { type: "append" };
1336
+ const emptyKey = type_ === "by_lot" ? "material_no_" : type_ === "by_number" ? "qty_" : null;
1337
+ if (emptyKey) {
1338
+ const fillIdx = sameIndexes.find((i) => !table[i]?.[emptyKey]);
1339
+ return fillIdx !== void 0 ? { type: "fill", index: fillIdx } : { type: "append" };
1340
+ }
1341
+ }
1342
+ const hasOtherProduct = plan.memberIndexes.some((i) => {
1343
+ const id = table[i]?.product_id_;
1344
+ return id && id !== scanRow.product_id_;
1345
+ });
1346
+ if (hasOtherProduct) return { type: "append" };
1347
+ throw new Error("匹配不到对应物料,请按规则上料或新增物料");
1348
+ }
1349
+ const EMPTY_PRODUCT_VERSION_ID = "__mc_no_selectable_product__";
1350
+ const EMPTY_LOT_NAME = "__mc_no_selectable_lot__";
1351
+ function isEmptyProductQuery(query) {
1352
+ const ids = query?.["id_.in"];
1353
+ return ids?.length === 1 && ids[0] === EMPTY_PRODUCT_VERSION_ID;
1354
+ }
1355
+ function buildProductIdQuery(options) {
1356
+ const { skipFilter, validator, tableData, row, rowIndex, enableSequenceLoading } = options;
1357
+ if (skipFilter) return void 0;
1358
+ const entryIdx = validator.resolveEntryIndex(row);
1359
+ if (entryIdx >= 0) {
1360
+ return toQuery(resolveGroupProductIds(validator, entryIdx, tableData));
1361
+ }
1362
+ if (enableSequenceLoading && rowIndex != null && rowIndex >= 0) {
1363
+ const indexes = resolveSequentialCandidateEntryIndexes(validator, tableData, rowIndex, row);
1364
+ if (indexes.length === 1) {
1365
+ return toQuery(resolveGroupProductIds(validator, indexes[0], tableData));
1366
+ }
1367
+ return toQuery(resolveUnassignedMaterialVersionIds(validator, tableData, row, rowIndex, true));
1368
+ }
1369
+ return toQuery(resolveUnassignedMaterialVersionIds(validator, tableData, row, void 0, false));
1370
+ }
1371
+ function buildMaterialNoQuery(options) {
1372
+ const { row, skipFilter, validator } = options;
1373
+ let baseQuery;
1374
+ if (row.product_id_) {
1375
+ baseQuery = {
1376
+ "product_id_.versionIn": [row.product_id_.split(":").pop()]
1377
+ };
1378
+ } else {
1379
+ const productQuery = buildProductIdQuery(options);
1380
+ if (!productQuery || isEmptyProductQuery(productQuery)) {
1381
+ baseQuery = { "product_id_.versionIn": [EMPTY_PRODUCT_VERSION_ID] };
1382
+ } else {
1383
+ const versionIds = productQuery["id_.in"].filter((id) => Boolean(id));
1384
+ baseQuery = { "product_id_.versionIn": versionIds };
1385
+ }
1386
+ }
1387
+ if (skipFilter) {
1388
+ return baseQuery;
1389
+ }
1390
+ const entryIdx = validator.resolveEntryIndex(row);
1391
+ if (entryIdx < 0) {
1392
+ return baseQuery;
1393
+ }
1394
+ const entry = validator.bomEntryValidators[entryIdx].bomEntry;
1395
+ if (!entry.specified_material_no_enabled_) {
1396
+ return baseQuery;
1397
+ }
1398
+ const names = (entry.specified_material_entries_ ?? []).map((e) => e.name_).filter(Boolean);
1399
+ return {
1400
+ ...baseQuery,
1401
+ "name_.in": names.length ? names : [EMPTY_LOT_NAME]
1402
+ };
1403
+ }
1404
+ function toVersionIds(ids) {
1405
+ return ids.map((id) => id.split(":").pop());
1406
+ }
1407
+ function toQuery(ids) {
1408
+ if (!ids.length) {
1409
+ return { "id_.in": [EMPTY_PRODUCT_VERSION_ID] };
1410
+ }
1411
+ return { "id_.in": toVersionIds(ids) };
1412
+ }
1413
+ function resolveKnownGroupEntryIndexes(validator, tableData, excludeRow) {
1414
+ const seen = /* @__PURE__ */ new Set();
1415
+ for (const tableRow of tableData) {
1416
+ if (tableRow.deleted_ || tableRow === excludeRow) continue;
1417
+ const idx = validator.resolveEntryIndex(tableRow);
1418
+ if (idx >= 0) seen.add(idx);
1419
+ }
1420
+ return Array.from(seen);
1421
+ }
1422
+ function resolveSequentialBounds(validator, tableData, rowIndex, excludeRow) {
1423
+ let prev = -1;
1424
+ let next = validator.bomEntryValidators.length;
1425
+ for (let i = rowIndex - 1; i >= 0; i--) {
1426
+ const tableRow = tableData[i];
1427
+ if (!tableRow || tableRow.deleted_ || tableRow === excludeRow) continue;
1428
+ const idx = validator.resolveEntryIndex(tableRow);
1429
+ if (idx >= 0) {
1430
+ prev = idx;
1431
+ break;
1432
+ }
1433
+ }
1434
+ for (let i = rowIndex + 1; i < tableData.length; i++) {
1435
+ const tableRow = tableData[i];
1436
+ if (!tableRow || tableRow.deleted_ || tableRow === excludeRow) continue;
1437
+ const idx = validator.resolveEntryIndex(tableRow);
1438
+ if (idx >= 0) {
1439
+ next = idx;
1440
+ break;
1441
+ }
1442
+ }
1443
+ return { prev, next };
1444
+ }
1445
+ function resolveSequentialCandidateEntryIndexes(validator, tableData, rowIndex, excludeRow) {
1446
+ const { prev, next } = resolveSequentialBounds(validator, tableData, rowIndex, excludeRow);
1447
+ const indexes = [];
1448
+ for (let i = prev + 1; i < next; i++) {
1449
+ indexes.push(i);
1450
+ }
1451
+ return indexes;
1452
+ }
1453
+ function resolveMaterialVersionIdsByEntryIndexes(validator, entryIndexes) {
1454
+ const result = /* @__PURE__ */ new Set();
1455
+ for (const idx of entryIndexes) {
1456
+ validator.bomEntryValidators[idx]?.productIds.forEach((id) => {
1457
+ result.add(id.split(":").pop());
1458
+ });
1459
+ }
1460
+ return Array.from(result);
1461
+ }
1462
+ function resolveGroupProductIds(validator, entryIdx, tableData) {
1463
+ const util = validator.bomEntryValidators[entryIdx];
1464
+ if (!util) return [];
1465
+ return util.getSelectableProductIds(tableData);
1466
+ }
1467
+ function resolveUnassignedMaterialVersionIds(validator, tableData, excludeRow, rowIndex, enableSequenceLoading = false) {
1468
+ const allIndexes = validator.bomEntryValidators.map((_, i) => i);
1469
+ const knownGroupIndexes = resolveKnownGroupEntryIndexes(validator, tableData, excludeRow);
1470
+ let candidateGroupIndexes;
1471
+ if (enableSequenceLoading && rowIndex != null && rowIndex >= 0) {
1472
+ const intervalIndexes = resolveSequentialCandidateEntryIndexes(
1473
+ validator,
1474
+ tableData,
1475
+ rowIndex,
1476
+ excludeRow
1477
+ );
1478
+ candidateGroupIndexes = intervalIndexes.filter((i) => !knownGroupIndexes.includes(i));
1479
+ } else {
1480
+ candidateGroupIndexes = allIndexes.filter((i) => !knownGroupIndexes.includes(i));
1481
+ }
1482
+ if (!candidateGroupIndexes.length) {
1483
+ return [];
1484
+ }
1485
+ return resolveMaterialVersionIdsByEntryIndexes(validator, candidateGroupIndexes);
1486
+ }
1487
+ const GROUP_MERGE_FIELDS = /* @__PURE__ */ new Set([
1488
+ "qty_required_",
1489
+ "qty_consumed_total_"
1490
+ ]);
1491
+ function isGroupMergeCell(tdInfo) {
1492
+ if (tdInfo.cellHidden || !tdInfo.cellWidget?.props) return false;
1493
+ const props = tdInfo.cellWidget.props;
1494
+ if (props.type === "serialnumber") return true;
1495
+ const field = props.field;
1496
+ return !!field && GROUP_MERGE_FIELDS.has(field);
1497
+ }
1498
+ function getGroupMergeKey(row, validator) {
1499
+ const entryIdx = validator.resolveEntryIndex(row);
1500
+ if (entryIdx >= 0) {
1501
+ return `bom:${validator.bomEntryValidators[entryIdx].bomEntry.id_}`;
1502
+ }
1503
+ if (row.bom_entry_id_) {
1504
+ return `bom:${row.bom_entry_id_}`;
1505
+ }
1506
+ return `row:${getRowId(row)}`;
1507
+ }
1508
+ function calcGroupRowSpans(rows, validator) {
1509
+ if (!rows.length) return [];
1510
+ const keys = rows.map((row) => getGroupMergeKey(row, validator));
1511
+ const spans = Array(rows.length).fill(1);
1512
+ for (let i = 0; i < keys.length; ) {
1513
+ let j = i + 1;
1514
+ while (j < keys.length && keys[j] === keys[i]) j++;
1515
+ const size = j - i;
1516
+ spans[i] = size;
1517
+ for (let k = i + 1; k < j; k++) {
1518
+ spans[k] = 0;
1519
+ }
1520
+ i = j;
1521
+ }
1522
+ return spans;
1523
+ }
1524
+ function calcGroupQtyConsumedTotal(entryIdx, tableData, validator) {
1525
+ if (entryIdx < 0) return 0;
1526
+ return tableData.reduce((sum, row) => {
1527
+ return validator.resolveEntryIndex(row) === entryIdx ? sum + (row.qty_ ?? 0) : sum;
1528
+ }, 0);
1529
+ }
1530
+ function syncGroupQtyConsumedTotals(tableData, validator) {
1531
+ const totals = /* @__PURE__ */ new Map();
1532
+ tableData.forEach((row) => {
1533
+ const entryIdx = validator.resolveEntryIndex(row);
1534
+ if (entryIdx < 0) {
1535
+ row.qty_consumed_total_ = void 0;
1536
+ return;
1537
+ }
1538
+ if (!totals.has(entryIdx)) {
1539
+ totals.set(entryIdx, calcGroupQtyConsumedTotal(entryIdx, tableData, validator));
1540
+ }
1541
+ row.qty_consumed_total_ = totals.get(entryIdx);
1542
+ });
1543
+ }
1544
+ const calculate = (...args) => window.NocodeAdapter.utils?.formulaCalculate?.(...args);
1364
1545
  class MCDataUtil {
1365
1546
  static allFields = [
1366
1547
  "product_id_",
@@ -1372,7 +1553,8 @@ class MCDataUtil {
1372
1553
  "expiration_date_",
1373
1554
  "qty_required_uom_id_",
1374
1555
  "qty_uom_id_",
1375
- "qty_transfer_"
1556
+ "qty_transfer_",
1557
+ "qty_consumed_total_"
1376
1558
  ];
1377
1559
  static editMCTable(row, data) {
1378
1560
  if (!row._MCTABLE) {
@@ -1434,10 +1616,10 @@ class MaterialConsumeTableController {
1434
1616
  this.bomEntriesValidator = new BomEntriesValidator(
1435
1617
  this.actualBomEntries,
1436
1618
  this.enableSequenceLoading,
1437
- this.materialNoNum,
1619
+ () => this.materialNoNum,
1438
1620
  this.tmplBomController.historyData,
1439
1621
  this.tmplBomController.materialNo,
1440
- this.mcPattern
1622
+ this.mcPattern === MaterialConsumptionPatternEnum.RECORD && !this.tmplBom.personal_bom_enabled_
1441
1623
  );
1442
1624
  }
1443
1625
  tmplBomController;
@@ -1465,8 +1647,18 @@ class MaterialConsumeTableController {
1465
1647
  unitConversionRules = [];
1466
1648
  /** 主表 formState(由组件 setup 注入),用于读取主表字段值 */
1467
1649
  mainFormState = ref({});
1468
- /** 批次数量 */
1650
+ /** 表单数据状态(由组件 setup 注入):未填报 / STASH / SUBMIT */
1651
+ dataStatus;
1652
+ /** 表单是否已暂存或提交(已处理过则不再跑初始化) */
1653
+ get isDataProcessed() {
1654
+ return ["STASH", "SUBMIT"].includes(this.dataStatus ?? "");
1655
+ }
1656
+ /** 批次数量或生产数量 */
1469
1657
  get materialNoNum() {
1658
+ const { required_qty_calc_rule_, product_qty_field_ } = this.tmplBom;
1659
+ if (required_qty_calc_rule_ === RequiredQtyCalcRule.ProductQty) {
1660
+ return product_qty_field_ ? this.mainFormState.value[product_qty_field_] : 0;
1661
+ }
1470
1662
  return this.tmplBomController.materialNoNum;
1471
1663
  }
1472
1664
  /** 物料消耗模式(自身没有配置的话取环境的默认值) */
@@ -1565,25 +1757,51 @@ class MaterialConsumeTableController {
1565
1757
  * 根据bom明细构造子表数据(初始化时)
1566
1758
  */
1567
1759
  calcFormState() {
1568
- if (this.tmplBom.material_loading_model_enabled_) ;
1569
- else if (this.isPersonalBom || this.tmplBom.bom_init_enabled_) {
1570
- return this.tmplBom.entries_.map((i) => {
1760
+ if (this.tmplBom.bom_init_enabled_) {
1761
+ return this.actualBomEntries.map((i) => {
1571
1762
  return {
1572
1763
  product_id_: i.product_id_,
1573
- qty_required_: i.qty_required_ * this.materialNoNum
1574
- // routing_operation_id_: this.tmplBomController.operationId,
1764
+ qty_required_: i.qty_required_ * this.materialNoNum,
1765
+ bom_entry_id_: i.id_
1575
1766
  };
1576
1767
  });
1577
1768
  }
1578
1769
  }
1770
+ /**
1771
+ * 未填报时初始化消耗表行数据
1772
+ * @param defaultData 子表行默认值(含工序等)
1773
+ */
1774
+ initTableData(defaultData) {
1775
+ if (this.isDataProcessed) return;
1776
+ const rows = this.calcFormState();
1777
+ if (!rows?.length) return;
1778
+ const tableRows = transformUtils.transformSourceData2SubTable(
1779
+ rows,
1780
+ {},
1781
+ defaultData
1782
+ );
1783
+ tableRows.forEach((row, i) => {
1784
+ ensureFrontRowKey(row);
1785
+ if (i === 0) {
1786
+ MCDataUtil.setRowEditing(row, true);
1787
+ } else {
1788
+ MCDataUtil.setRowEditing(row, !this.enableSequenceLoading);
1789
+ }
1790
+ });
1791
+ this.actualTableData = tableRows;
1792
+ }
1579
1793
  /**
1580
1794
  * 根据数据计算需要禁用的字段
1581
1795
  * @param row
1582
1796
  * @return {*}
1583
1797
  */
1584
1798
  calcDisabledFields(row) {
1585
- const disabledKeys = ["qty_consumed_"];
1586
- const isRecordPattern = this.mcPattern === MaterialConsumptionPatternEnum.RECORD;
1799
+ const disabledKeys = [
1800
+ "qty_consumed_",
1801
+ "sort_num_",
1802
+ "qty_consumed_total_"
1803
+ ];
1804
+ const isRecordPattern = this.mcPattern === MaterialConsumptionPatternEnum.RECORD && !this.tmplBom.personal_bom_enabled_;
1587
1805
  if (!isRecordPattern) {
1588
1806
  disabledKeys.push("qty_required_");
1589
1807
  }
@@ -1600,13 +1818,38 @@ class MaterialConsumeTableController {
1600
1818
  * @return {*}
1601
1819
  */
1602
1820
  getProductQuery() {
1603
- if (this.mcPattern === MaterialConsumptionPatternEnum.RECORD) {
1821
+ if (this.mcPattern === MaterialConsumptionPatternEnum.RECORD && !this.tmplBom.personal_bom_enabled_) {
1604
1822
  return void 0;
1605
1823
  }
1606
1824
  return {
1607
1825
  "id_.in": this.bomEntriesValidator.getAllMaterialIds()
1608
1826
  };
1609
1827
  }
1828
+ /**
1829
+ * 行级 product_id_ / material_no_ 查询共用入参
1830
+ */
1831
+ buildProductQueryOptions(row, rowIndex) {
1832
+ return {
1833
+ validator: this.bomEntriesValidator,
1834
+ tableData: this.actualTableData,
1835
+ row,
1836
+ rowIndex,
1837
+ enableSequenceLoading: this.enableSequenceLoading,
1838
+ skipFilter: this.mcPattern === MaterialConsumptionPatternEnum.RECORD && !this.tmplBom.personal_bom_enabled_
1839
+ };
1840
+ }
1841
+ /**
1842
+ * 行级 product_id_ 下拉过滤(覆盖全局 id_.in)
1843
+ */
1844
+ getProductQueryForRow(row, rowIndex) {
1845
+ return buildProductIdQuery(this.buildProductQueryOptions(row, rowIndex));
1846
+ }
1847
+ /**
1848
+ * 行级 material_no_ 批次过滤:有物料按物料;无物料与 product_id_ 可选范围一致
1849
+ */
1850
+ getMaterialNoQueryForRow(row, rowIndex) {
1851
+ return buildMaterialNoQuery(this.buildProductQueryOptions(row, rowIndex));
1852
+ }
1610
1853
  /**
1611
1854
  * 是否是第一行且物料是空行
1612
1855
  * @return {*}
@@ -1614,17 +1857,32 @@ class MaterialConsumeTableController {
1614
1857
  isFirstBlankRow() {
1615
1858
  return this.actualTableData.length === 1 && !this.actualTableData[0].product_id_;
1616
1859
  }
1860
+ /**
1861
+ * 是否有正在编辑的组。
1862
+ * 一组可多行同时为编辑态;同时只能有一组处于编辑态。
1863
+ */
1864
+ hasEditingGroup(showMessage = true) {
1865
+ try {
1866
+ const hasEditing = this.bomEntriesValidator.hasEditingGroup(this.actualTableData);
1867
+ if (hasEditing && showMessage) {
1868
+ this.error($t("sys.edhr.mcTable.onlyOneEditingRow"));
1869
+ }
1870
+ return hasEditing;
1871
+ } catch (e) {
1872
+ if (showMessage && e?.message) {
1873
+ this.error(e.message);
1874
+ }
1875
+ return true;
1876
+ }
1877
+ }
1617
1878
  /**
1618
1879
  * 解析扫码的数据
1619
1880
  * 并判断是否能存入表中,返回对象则表示可以存入
1620
1881
  * @param str
1621
1882
  */
1622
- async parseScanStr(str) {
1623
- if (!this.isFirstBlankRow() && this.hasEditingRow()) {
1624
- return;
1625
- }
1626
- const isRecordPattern = this.mcPattern === MaterialConsumptionPatternEnum.RECORD;
1627
- const data = getParseRuleValue(str, this.scanRules);
1883
+ async parseScanStr(data, transformedData) {
1884
+ await this.bomEntriesValidator.hasEditingGroup(this.actualTableData);
1885
+ const isRecordPattern = this.mcPattern === MaterialConsumptionPatternEnum.RECORD && !this.tmplBom.personal_bom_enabled_;
1628
1886
  console.log("parseScanStr", data);
1629
1887
  const arr = await materialCheck({
1630
1888
  material_no_: data.materialCode,
@@ -1633,54 +1891,50 @@ class MaterialConsumeTableController {
1633
1891
  validate_: data.expiration,
1634
1892
  // 记录模式传null,后台就不校验了
1635
1893
  bom_entries_: isRecordPattern ? null : this.actualBomEntries,
1636
- operation_id_: this.tmplBomController.operationId
1894
+ operation_id_: this.tmplBomController.operationId,
1895
+ unique_code_: data.uniqueCode,
1896
+ // 不开启条码解析时,参数配置的唯一码
1897
+ bar_code_enabled_: !this.tmplBom.disable_barcode_parsing_
1637
1898
  }) || (isRecordPattern ? [{ productionIdentificationName: data.lot }] : null);
1638
1899
  if (!arr) {
1639
- this.error($t("sys.edhr.mcTable.notInBom"));
1900
+ this.error("匹配不到对应物料,请按规则上料或新增物料");
1640
1901
  return;
1641
1902
  }
1642
1903
  let materialData = arr[0];
1643
- if (arr.length > 1 && !isRecordPattern) {
1644
- const ids = this.actualTableData.map((i) => i.product_id_);
1645
- const find = arr.find((j) => ids.includes(j.materialId));
1646
- if (!find) {
1647
- throw new Error($t("sys.edhr.mcTable.noMatchMaterial"));
1904
+ if (arr.length > 1) {
1905
+ const selected = await MaterialConsumeTableController.render.openMultiRowsModal({
1906
+ rows: arr
1907
+ });
1908
+ if (!selected) {
1909
+ return;
1648
1910
  }
1649
- materialData = find;
1911
+ materialData = selected;
1912
+ } else if (materialData?.productionIdentificationIsLocked) {
1913
+ const msg = await getLotLockedReason(materialData.productionIdentificationId);
1914
+ this.error(msg);
1915
+ return;
1650
1916
  }
1651
1917
  const row = {
1652
1918
  product_id_: materialData.materialId,
1653
1919
  material_no_: materialData.productionIdentificationName,
1654
1920
  qty_: data.qty,
1655
- is_confirmed_: false
1921
+ is_confirmed_: false,
1922
+ expiration_date_: data.expiration
1656
1923
  };
1657
1924
  if (isRecordPattern && !row.product_id_) {
1658
1925
  row._scanFallback = true;
1659
1926
  }
1660
- if (this.scanRuleProps?.fillMapArr?.length) {
1661
- const fillData = calcFillData(data, this.scanRuleProps.fillMapArr);
1662
- console.log("fillData", fillData);
1663
- Object.assign(row, fillData);
1664
- }
1665
- if (data.expiration) {
1666
- row.expiration_date_ = dayjs(data.expiration).format("YYYY-MM-DD");
1667
- }
1927
+ Object.assign(row, transformedData);
1668
1928
  this.setDefaultValue(row);
1669
1929
  try {
1670
- const newArr = this.bomEntriesValidator.mergeRowInArr(row, this.actualTableData);
1671
- await this.bomEntriesValidator.validateScanCanInsert(newArr);
1672
- if (this.isOnlyEmptyRow()) {
1673
- const firstRow = this.actualTableData[0];
1674
- defaults(row, firstRow);
1675
- }
1676
- this.tableDataRef.value = newArr;
1677
- const editingRow = this.actualTableData.find((i) => !i.is_confirmed_);
1678
- if (editingRow && row.product_id_) {
1679
- this.confirm(editingRow);
1680
- }
1930
+ const plan = await this.bomEntriesValidator.validateScanCanInsert(row, this.actualTableData);
1931
+ this.tableDataRef.value = await applyScanFillPlan(this.actualTableData, row, plan, {
1932
+ validateCurrentGroupForSwitch: (table, current) => this.bomEntriesValidator.validateCurrentGroupForSwitch(table, current)
1933
+ });
1934
+ this.updateDerivedQtyFields();
1681
1935
  } catch (e) {
1682
1936
  console.error(e);
1683
- if (e.message) {
1937
+ if (e?.message) {
1684
1938
  this.error(e.message);
1685
1939
  }
1686
1940
  }
@@ -1695,7 +1949,6 @@ class MaterialConsumeTableController {
1695
1949
  if (this.isScanOpen) {
1696
1950
  return;
1697
1951
  }
1698
- console.log("open-------", this);
1699
1952
  if (!this.tmplBom.disable_barcode_parsing_ && !this.scanRuleInfo || this.tmplBom.disable_barcode_parsing_ && !this.scanParamType) {
1700
1953
  this.error($t("sys.edhr.mcTable.scanRuleNotFound"));
1701
1954
  return;
@@ -1708,12 +1961,19 @@ class MaterialConsumeTableController {
1708
1961
  formModelController: this.formModelController,
1709
1962
  scanRules: this.scanRuleProps,
1710
1963
  scanParam: this.scanParamType,
1711
- onScan: async ({ str }) => {
1712
- console.log("onScan", str);
1964
+ onScan: async ({ str, parsedValue, transformedData }) => {
1965
+ console.log("onScan", str, parsedValue);
1713
1966
  if (!str) {
1714
1967
  return;
1715
1968
  }
1716
- await this.parseScanStr(str);
1969
+ try {
1970
+ await this.validateExpiration({ expiration_date_: parsedValue.expiration });
1971
+ await this.parseScanStr(parsedValue, transformedData);
1972
+ } catch (e) {
1973
+ if (e?.message) {
1974
+ this.error(e.message);
1975
+ }
1976
+ }
1717
1977
  }
1718
1978
  });
1719
1979
  this.isScanOpen = false;
@@ -1726,7 +1986,7 @@ class MaterialConsumeTableController {
1726
1986
  if (!this.actualBomEntries) {
1727
1987
  return;
1728
1988
  }
1729
- await MaterialConsumeTableController.render.openBomModal({
1989
+ await MaterialConsumeTableController.render?.openBomModal({
1730
1990
  bomList: this.actualBomEntries,
1731
1991
  onSubstitute: async () => {
1732
1992
  console.log("一键导入数据逻辑");
@@ -1743,17 +2003,36 @@ class MaterialConsumeTableController {
1743
2003
  this.formModelController = opts.formModelController;
1744
2004
  this.unitConversionRules = opts.unitConversionRules ?? [];
1745
2005
  this.mainFormState = opts.mainFormState ?? ref({});
1746
- console.log("setup", this.tableDataRef);
2006
+ this.dataStatus = opts.dataStatus;
2007
+ this.initTableData(opts.defaultRowData);
1747
2008
  if (this.actualTableData.length === 1) {
1748
2009
  const firstRow = this.actualTableData[0];
1749
2010
  if (!firstRow.product_id_) {
1750
2011
  MCDataUtil.setRowEditing(firstRow, true);
1751
2012
  }
1752
2013
  }
2014
+ watch(
2015
+ () => this.materialNoNum,
2016
+ () => this.syncQtyRequiredFromBom(),
2017
+ { immediate: true }
2018
+ );
1753
2019
  onUnmounted(() => {
1754
2020
  MaterialConsumeTableController.render.destroyAllModals();
1755
2021
  });
1756
2022
  }
2023
+ /**
2024
+ * 按当前 materialNoNum 回写各行 qty_required_(校验侧 total 已通过 getter 实时读取)
2025
+ */
2026
+ syncQtyRequiredFromBom() {
2027
+ this.actualTableData.forEach((row) => {
2028
+ if (!row.product_id_) return;
2029
+ const util = this.bomEntriesValidator.findUtilByProductId(row.product_id_);
2030
+ if (util) {
2031
+ row.qty_required_ = util.total;
2032
+ }
2033
+ });
2034
+ this.updateDerivedQtyFields();
2035
+ }
1757
2036
  /** 校验有效期 */
1758
2037
  validateExpiration(row) {
1759
2038
  if (row.expiration_date_) {
@@ -1798,7 +2077,7 @@ class MaterialConsumeTableController {
1798
2077
  return acc;
1799
2078
  }, {});
1800
2079
  try {
1801
- const res = await calculate$1(formulaContent, formData);
2080
+ const res = await calculate(formulaContent, formData);
1802
2081
  Object.assign(row, {
1803
2082
  qty_transfer_: res,
1804
2083
  qty_transfer_uom_id_: targetUnitId,
@@ -1875,14 +2154,12 @@ class MaterialConsumeTableController {
1875
2154
  return;
1876
2155
  }
1877
2156
  let errorObj;
1878
- const hasEditing = this.hasEditingRow(false);
1879
- if (hasEditing) {
1880
- errorObj = this.calcErrorObj($t("sys.edhr.mcTable.hasEditingRow"));
1881
- }
1882
2157
  try {
1883
- this.bomEntriesValidator.validateSequenceLoading(void 0, this.actualTableData);
2158
+ if (this.mcPattern !== MaterialConsumptionPatternEnum.RECORD && !this.tmplBom.personal_bom_enabled_) {
2159
+ await this.bomEntriesValidator.validateAllRows(this.actualTableData);
2160
+ }
1884
2161
  } catch (e) {
1885
- if (e.message) {
2162
+ if (e?.message) {
1886
2163
  errorObj = this.calcErrorObj(e.message);
1887
2164
  }
1888
2165
  }
@@ -1900,19 +2177,36 @@ class MaterialConsumeTableController {
1900
2177
  return hasEditing;
1901
2178
  }
1902
2179
  /**
1903
- * 选中行开启编辑
2180
+ * 选中行开启编辑(顺序上料:校验当前编辑组后整组切换;非顺序上料:始终编辑态,无需操作)
1904
2181
  * @param row
1905
2182
  */
1906
- editRow(row) {
1907
- if (this.hasEditingRow()) {
2183
+ async editRow(row) {
2184
+ if (!this.enableSequenceLoading) {
2185
+ return;
2186
+ }
2187
+ const entryIdx = this.bomEntriesValidator.resolveEntryIndex(row);
2188
+ const targetUtil = entryIdx >= 0 ? this.bomEntriesValidator.bomEntryValidators[entryIdx] : void 0;
2189
+ if (!targetUtil) {
2190
+ MCDataUtil.setRowEditing(row, true);
1908
2191
  return;
1909
2192
  }
1910
- const isLast = this.actualTableData[this.actualTableData.length - 1] === row;
1911
- if (this.enableSequenceLoading && !isLast) {
1912
- this.error($t("sys.edhr.mcTable.onlyLastRowCanEdit"));
2193
+ const targetRows = this.actualTableData.filter((r) => isRowInBomGroup(r, targetUtil));
2194
+ if (targetRows.length && targetRows.every((r) => !r.is_confirmed_)) {
1913
2195
  return;
1914
2196
  }
1915
- MCDataUtil.setRowEditing(row, true);
2197
+ const current = this.bomEntriesValidator.findSequenceBomEntry(this.actualTableData);
2198
+ if (current && current !== targetUtil) {
2199
+ try {
2200
+ await this.bomEntriesValidator.validateCurrentGroupForSwitch(this.actualTableData, current);
2201
+ } catch (e) {
2202
+ if (e?.message) {
2203
+ this.error(e.message);
2204
+ }
2205
+ return;
2206
+ }
2207
+ setGroupEditState(this.actualTableData, current, false);
2208
+ }
2209
+ setGroupEditState(this.actualTableData, targetUtil, true);
1916
2210
  }
1917
2211
  /**
1918
2212
  * 更新整个数组的所有行的已消耗数量
@@ -1930,8 +2224,7 @@ class MaterialConsumeTableController {
1930
2224
  const beforeArr = this.actualTableData.slice(0, index + 1);
1931
2225
  if (util) {
1932
2226
  total += util.hasConsumed;
1933
- const filterGroupData = util.filterGroupData(beforeArr);
1934
- filterGroupData.forEach((i) => {
2227
+ util.filterGroupData(beforeArr).forEach((i) => {
1935
2228
  total += i.qty_ ?? 0;
1936
2229
  });
1937
2230
  row.qty_consumed_ = total;
@@ -1941,6 +2234,19 @@ class MaterialConsumeTableController {
1941
2234
  modifySingleRow(index);
1942
2235
  }
1943
2236
  }
2237
+ /**
2238
+ * 组级:更新 qty_consumed_total_(同组 qty_ 之和)
2239
+ */
2240
+ updateGroupQtyConsumedTotal() {
2241
+ syncGroupQtyConsumedTotals(this.actualTableData, this.bomEntriesValidator);
2242
+ }
2243
+ /**
2244
+ * qty 相关派生字段统一入口(改 qty_ / 扫码 / 删行 等都走这里)
2245
+ */
2246
+ updateDerivedQtyFields() {
2247
+ this.updateRowConsumed();
2248
+ this.updateGroupQtyConsumedTotal();
2249
+ }
1944
2250
  /**
1945
2251
  * 设置默认值,如工序,需求数量/已消耗数量
1946
2252
  * @param row
@@ -1962,7 +2268,7 @@ class MaterialConsumeTableController {
1962
2268
  * 统一处理表格内部的字段的值变更
1963
2269
  * @param opts
1964
2270
  */
1965
- handleChange(opts) {
2271
+ async handleChange(opts) {
1966
2272
  const { field, row, value, option } = opts;
1967
2273
  console.log("handleChange", opts);
1968
2274
  if (field === "product_id_") {
@@ -1975,11 +2281,18 @@ class MaterialConsumeTableController {
1975
2281
  row.qty_required_ = void 0;
1976
2282
  this.setDefaultValue(row);
1977
2283
  } else if (field === "material_no_") {
2284
+ if (option?.is_locked_) {
2285
+ row.material_no_ = void 0;
2286
+ row.material_no__id_ = void 0;
2287
+ const msg = await getLotLockedReason(option.id_);
2288
+ this.error(msg);
2289
+ return;
2290
+ }
1978
2291
  row.product_id_ = option.product_id_;
1979
2292
  row.expiration_date_ = option.validate_;
1980
2293
  this.setDefaultValue(row);
1981
2294
  } else if (field === "qty_") {
1982
- this.updateRowConsumed();
2295
+ this.updateDerivedQtyFields();
1983
2296
  }
1984
2297
  }
1985
2298
  }
@@ -2034,6 +2347,7 @@ var SubTableActionEnum = /* @__PURE__ */ ((SubTableActionEnum2) => {
2034
2347
  SubTableActionEnum2["VIEW_BOM"] = "VIEW_BOM";
2035
2348
  SubTableActionEnum2["CHANGE_PARSE_RULE"] = "CHANGE_PARSE_RULE";
2036
2349
  SubTableActionEnum2["RowEdit"] = "rowEdit";
2350
+ SubTableActionEnum2["Insert1GroupAfter"] = "insert1GroupAfter";
2037
2351
  return SubTableActionEnum2;
2038
2352
  })(SubTableActionEnum || {});
2039
2353
  var SubTableActionMenuTypeEnum = /* @__PURE__ */ ((SubTableActionMenuTypeEnum2) => {
@@ -2081,6 +2395,12 @@ function getMenuByAction(type) {
2081
2395
  label: "加一行",
2082
2396
  icon: "icon-jiayihang"
2083
2397
  },
2398
+ [SubTableActionEnum.Insert1GroupAfter]: {
2399
+ type: SubTableActionMenuTypeEnum.ACTION,
2400
+ key: SubTableActionEnum.Insert1GroupAfter,
2401
+ label: "加一组",
2402
+ icon: "icon-jiayihang"
2403
+ },
2084
2404
  [SubTableActionEnum.CopyRowAfter]: {
2085
2405
  type: SubTableActionMenuTypeEnum.ACTION,
2086
2406
  key: SubTableActionEnum.CopyRowAfter,
@@ -2532,161 +2852,8 @@ class SubTableCore {
2532
2852
  console.log(this.ctx.widget.props.tableTitle, "处理表单按钮点击事件", params);
2533
2853
  }
2534
2854
  }
2535
- const identify = (...args) => window.NocodeAdapter.utils?.formulaIdentify?.(...args) ?? [];
2536
- const calculate = (...args) => window.NocodeAdapter.utils?.formulaCalculate?.(...args);
2537
- function useDependency(widget, props) {
2538
- const { field, isFieldModel, fieldLink, subModelKey, newSpecificConfig } = widget.props;
2539
- const fieldWidget = ref(subModelKey ? cloneDeep(props.widget) : props.widget);
2540
- watch(
2541
- () => props.widget.props,
2542
- (newProps) => {
2543
- Object.assign(fieldWidget.value.props, newProps);
2544
- }
2545
- );
2546
- const { currentPageFormState } = useCurrentPageFormState();
2547
- const targetFieldId = field ? isFieldModel ? fieldLink : field : "";
2548
- const configDependency = widget.props.componentDependency?.configDependency || {};
2549
- const readonly_expression = configDependency[Dependency_ENUM.READONLY]?.expression;
2550
- const readonly_value = configDependency[Dependency_ENUM.READONLY]?.value;
2551
- if (readonly_value && readonly_expression) {
2552
- insetDep(
2553
- {
2554
- expression: readonly_expression,
2555
- formState: currentPageFormState.value
2556
- },
2557
- (res) => {
2558
- fieldWidget.value.props.field_readonly = !!res;
2559
- }
2560
- );
2561
- }
2562
- const field_required = widget.props?.newSpecificConfig?.newRequired;
2563
- const required_expression = configDependency[Dependency_ENUM.REQUIRED]?.expression;
2564
- const required_value = configDependency[Dependency_ENUM.REQUIRED]?.value;
2565
- if (!field_required && required_value && required_expression) {
2566
- insetDep(
2567
- {
2568
- expression: required_expression,
2569
- formState: currentPageFormState.value
2570
- },
2571
- (res) => {
2572
- fieldWidget.value.props.required = !!res;
2573
- }
2574
- );
2575
- }
2576
- if (field_required) {
2577
- fieldWidget.value.props.required = true;
2578
- }
2579
- const field_disabled = widget.props.disabled;
2580
- const disabled_expression = configDependency[Dependency_ENUM.DISABLED]?.expression;
2581
- const disabled_value = configDependency[Dependency_ENUM.DISABLED]?.value;
2582
- if (!field_disabled && disabled_value && disabled_expression) {
2583
- insetDep(
2584
- {
2585
- expression: disabled_expression,
2586
- formState: currentPageFormState.value
2587
- },
2588
- (res) => {
2589
- fieldWidget.value.props.disabled = !!res;
2590
- }
2591
- );
2592
- }
2593
- const assignment_expression = configDependency[Dependency_ENUM.ASSIGNMENT]?.expression;
2594
- const strategy = configDependency[Dependency_ENUM.ASSIGNMENT]?.strategy;
2595
- if (assignment_expression) {
2596
- insetDep(
2597
- {
2598
- expression: assignment_expression,
2599
- formState: currentPageFormState.value
2600
- },
2601
- (res) => {
2602
- const formattedValue = formatDateCompliance(res, newSpecificConfig?.mappingType);
2603
- props.formData[field] = formattedValue;
2604
- }
2605
- );
2606
- }
2607
- if (!props.formData._OPCT) {
2608
- props.formData._OPCT = { _DICT: {} };
2609
- }
2610
- const formRowData = toRef(() => {
2611
- if (isFieldModel) {
2612
- return props.formData._OPCT;
2613
- }
2614
- return props.formData;
2615
- });
2616
- const value = computed({
2617
- get() {
2618
- if (targetFieldId) {
2619
- return formRowData.value[targetFieldId];
2620
- }
2621
- return "";
2622
- },
2623
- set(val) {
2624
- if (targetFieldId && !!assignment_expression && strategy === ASSIGNMENTSTRATEGY_ENUM.alwaysCover)
2625
- return;
2626
- formRowData.value[targetFieldId] = val;
2627
- }
2628
- });
2629
- function insetDep({ expression, formState }, callback) {
2630
- if (!expression || expression === "true") {
2631
- callback(true);
2632
- return;
2633
- }
2634
- const identifyArgs = identify(expression);
2635
- const cacheFormFields = computed(() => {
2636
- return identifyArgs.reduce((total, i) => {
2637
- const value2 = i.startsWith("_.") ? props.formData[i.slice(2)] : formState[i];
2638
- total[i] = value2;
2639
- return total;
2640
- }, {});
2641
- });
2642
- watchDebounced(
2643
- cacheFormFields,
2644
- () => {
2645
- calculate(expression, cacheFormFields.value).then(callback);
2646
- },
2647
- {
2648
- debounce: 200,
2649
- immediate: true,
2650
- deep: true
2651
- }
2652
- );
2653
- }
2654
- return { value, formRowData, targetFieldId, fieldWidget };
2655
- }
2656
- function formatDateCompliance(value, fieldTypeVal) {
2657
- if (!value) {
2658
- return value === 0 || value === false ? value : null;
2659
- }
2660
- const valueStr = String(value).trim();
2661
- if (fieldTypeVal === FIELD_TYPE.DATE) {
2662
- const dateMatch = valueStr.match(/^(\d{4}-\d{2}-\d{2})/);
2663
- if (!dateMatch) {
2664
- return "";
2665
- }
2666
- return dateMatch[1];
2667
- }
2668
- if (fieldTypeVal === FIELD_TYPE.DATE_TIME) {
2669
- if (/^\d{4}-\d{2}-\d{2}$/.test(valueStr)) {
2670
- return `${valueStr} 00:00:00`;
2671
- }
2672
- if (/^\d{4}-\d{2}-\d{2}\s\d{1,2}:\d{2}:\d{2}$/.test(valueStr)) {
2673
- return valueStr;
2674
- }
2675
- if (/^\d{4}-\d{2}-\d{2}\s\d{1,2}:\d{2}$/.test(valueStr)) {
2676
- return `${valueStr}:00`;
2677
- }
2678
- return "";
2679
- }
2680
- if (fieldTypeVal === FIELD_TYPE.TIME) {
2681
- const timeMatch = valueStr.match(/(\d{1,2}:\d{2}(?::\d{2})?)/);
2682
- if (timeMatch) {
2683
- return timeMatch[1];
2684
- }
2685
- return "";
2686
- }
2687
- return value;
2688
- }
2689
2855
  class DeviceLinkTmplUtil {
2856
+ static DEFAULT_RECOMMENDED_PROMPT = "任务:图片OCR文字提取\n规则:不虚构内容,找不到数据返回空,仅输出提取结果\n结果填充至${目标字段}\n填写提取规则:";
2690
2857
  /**
2691
2858
  * 创建模板数据
2692
2859
  * @param type
@@ -2699,8 +2866,19 @@ class DeviceLinkTmplUtil {
2699
2866
  };
2700
2867
  if (type === DeviceLink.TmplTypeEnum.AI_OCR) {
2701
2868
  Object.assign(tmpl, {
2869
+ name: "",
2870
+ deviceName: "",
2871
+ modelPrecision: void 0,
2872
+ enableAdvancedConfig: false,
2873
+ promptMode: "RECOMMENDED",
2874
+ recommendedPrompt: this.DEFAULT_RECOMMENDED_PROMPT,
2875
+ enableDenoise: false,
2876
+ enableContrast: false,
2877
+ enableBinarize: false,
2878
+ extraPrompt: "",
2702
2879
  identifyParams: [
2703
2880
  {
2881
+ id: uuid2(16),
2704
2882
  prompt: void 0,
2705
2883
  formField: void 0
2706
2884
  }
@@ -2711,6 +2889,30 @@ class DeviceLinkTmplUtil {
2711
2889
  }
2712
2890
  return tmpl;
2713
2891
  }
2892
+ /**
2893
+ * 补齐 OCR 模板新增字段,并保持历史配置的原有行为。
2894
+ * 历史模板没有提示词模式时按原来的普通模式处理。
2895
+ */
2896
+ static normalizeAIOcrTmpl(tmpl) {
2897
+ const hasAdvancedConfig = !!tmpl.enableDenoise || !!tmpl.enableContrast || !!tmpl.enableBinarize;
2898
+ const identifyParams = tmpl.identifyParams?.length ? tmpl.identifyParams : [{ prompt: void 0, formField: void 0 }];
2899
+ return {
2900
+ ...tmpl,
2901
+ name: tmpl.name ?? "",
2902
+ deviceName: tmpl.deviceName ?? "",
2903
+ enableAdvancedConfig: tmpl.enableAdvancedConfig ?? hasAdvancedConfig,
2904
+ promptMode: tmpl.promptMode ?? "NORMAL",
2905
+ recommendedPrompt: tmpl.recommendedPrompt ?? this.DEFAULT_RECOMMENDED_PROMPT,
2906
+ enableDenoise: tmpl.enableDenoise ?? false,
2907
+ enableContrast: tmpl.enableContrast ?? false,
2908
+ enableBinarize: tmpl.enableBinarize ?? false,
2909
+ extraPrompt: tmpl.extraPrompt ?? "",
2910
+ identifyParams: identifyParams.map((item) => ({
2911
+ ...item,
2912
+ id: item.id || uuid2(16)
2913
+ }))
2914
+ };
2915
+ }
2714
2916
  /**
2715
2917
  * 计算完整的提示词
2716
2918
  * @static
@@ -2718,13 +2920,20 @@ class DeviceLinkTmplUtil {
2718
2920
  * @return {*}
2719
2921
  */
2720
2922
  static calcEntirePrompt(tmpl) {
2721
- const paramsStr = tmpl.identifyParams?.map((item) => {
2722
- return `图中${item.prompt}绑定${item.formField?.split(".")[1]}字段`;
2723
- }).join(",");
2724
- const jsonObj = tmpl.identifyParams?.reduce((acc, cur) => {
2725
- acc[cur.formField?.split(".")[1]] = {
2726
- value: null
2727
- };
2923
+ if (tmpl.promptMode === "RECOMMENDED") {
2924
+ return tmpl.recommendedPrompt ?? this.DEFAULT_RECOMMENDED_PROMPT;
2925
+ }
2926
+ const validParams = (tmpl.identifyParams || []).map((item) => ({
2927
+ prompt: item.prompt?.trim(),
2928
+ fieldKey: item.formField?.split(".").at(-1)
2929
+ })).filter(
2930
+ (item) => Boolean(item.prompt && item.fieldKey)
2931
+ );
2932
+ const paramsStr = validParams.map((item) => `图中${item.prompt}绑定${item.fieldKey}字段`).join(",");
2933
+ const jsonObj = validParams.reduce((acc, item) => {
2934
+ if (!Object.prototype.hasOwnProperty.call(acc, item.fieldKey)) {
2935
+ acc[item.fieldKey] = { value: null };
2936
+ }
2728
2937
  return acc;
2729
2938
  }, {});
2730
2939
  const result = `这是一台${tmpl.deviceName ?? ""}设备/仪器图片,${paramsStr},请识别图片中的读数,以
@@ -2878,6 +3087,7 @@ class DeviceConnector {
2878
3087
  }
2879
3088
  }
2880
3089
  }
3090
+ const OCR_MODEL_PRECISION_ENUM_KEY = "enu_model_precision";
2881
3091
  class FormTmplConfigController {
2882
3092
  /** 为了方便挂载到 word 中去 */
2883
3093
  TmplUtil = DeviceLinkTmplUtil;
@@ -2891,7 +3101,8 @@ class FormTmplConfigController {
2891
3101
  tmpls: [],
2892
3102
  runningTmpls: [],
2893
3103
  IOTPermission: false,
2894
- OCRPermission: false
3104
+ OCRPermission: false,
3105
+ OCRModelPrecisionOptions: []
2895
3106
  });
2896
3107
  /** 表单模板id */
2897
3108
  tmplId = "";
@@ -2904,6 +3115,22 @@ class FormTmplConfigController {
2904
3115
  this.state.IOTPermission = await api.platform.license.getModuleAuth({ module: "IOT" }) || false;
2905
3116
  this.state.OCRPermission = await api.apaas.onlineFormTmpl.getIsOcrGranted() || false;
2906
3117
  }
3118
+ /**
3119
+ * 从枚举模型加载 OCR 模型精度,避免前端硬编码枚举值。
3120
+ */
3121
+ async refreshOcrModelPrecisionOptions() {
3122
+ try {
3123
+ const result = await api.apaas.designerCommon.getEnumModelFieldList({
3124
+ enumModelKey: OCR_MODEL_PRECISION_ENUM_KEY,
3125
+ pageNo: 1,
3126
+ pageSize: 100
3127
+ });
3128
+ this.state.OCRModelPrecisionOptions = (result?.records || []).filter((item) => item.text && item.value).map((item) => ({ label: item.text, value: item.value }));
3129
+ } catch {
3130
+ this.state.OCRModelPrecisionOptions = [];
3131
+ }
3132
+ return this.state.OCRModelPrecisionOptions;
3133
+ }
2907
3134
  /**
2908
3135
  * 初始化
2909
3136
  *
@@ -2925,7 +3152,12 @@ class FormTmplConfigController {
2925
3152
  setConfigStr(configStr) {
2926
3153
  console.log("配置信息", configStr);
2927
3154
  const config = configStr ? JSON.parse(configStr) : {};
2928
- this.state.tmpls = config.tmpls || [];
3155
+ this.state.tmpls = (config.tmpls || []).map((tmpl) => {
3156
+ if (tmpl.type === DeviceLink.TmplTypeEnum.AI_OCR) {
3157
+ return this.TmplUtil.normalizeAIOcrTmpl(tmpl);
3158
+ }
3159
+ return tmpl;
3160
+ });
2929
3161
  }
2930
3162
  getConfigStr() {
2931
3163
  const cloneTmpls = cloneDeep(this.state.tmpls);
@@ -3007,12 +3239,12 @@ function useFormTmplConfig() {
3007
3239
  injectController
3008
3240
  };
3009
3241
  }
3010
- const _hoisted_1$6 = ["data-merge", "data-fill-direction"];
3242
+ const _hoisted_1$5 = ["data-merge", "data-fill-direction"];
3011
3243
  const _hoisted_2$1 = {
3012
3244
  key: 0,
3013
3245
  class: "absolute z-9 top-1/2 right-0 w-0 h-0 -translate-y-4"
3014
3246
  };
3015
- const _sfc_main$8 = /* @__PURE__ */ defineComponent({
3247
+ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
3016
3248
  __name: "border-td",
3017
3249
  props: {
3018
3250
  border: {},
@@ -3078,24 +3310,24 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
3078
3310
  _ctx.$slots.tableAction ? (openBlock(), createElementBlock("div", _hoisted_2$1, [
3079
3311
  renderSlot(_ctx.$slots, "tableAction", {}, void 0, true)
3080
3312
  ])) : createCommentVNode("", true)
3081
- ], 16, _hoisted_1$6);
3313
+ ], 16, _hoisted_1$5);
3082
3314
  };
3083
3315
  }
3084
3316
  });
3085
- const BorderTD = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-5f774f44"]]);
3086
- const _sfc_main$7 = {};
3087
- const _hoisted_1$5 = { class: "nocode-loading" };
3317
+ const BorderTD = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-5f774f44"]]);
3318
+ const _sfc_main$6 = {};
3319
+ const _hoisted_1$4 = { class: "nocode-loading" };
3088
3320
  function _sfc_render(_ctx, _cache) {
3089
- return openBlock(), createElementBlock("div", _hoisted_1$5, [..._cache[0] || (_cache[0] = [
3321
+ return openBlock(), createElementBlock("div", _hoisted_1$4, [..._cache[0] || (_cache[0] = [
3090
3322
  createElementVNode("div", { class: "nocode-shape shape-1" }, null, -1),
3091
3323
  createElementVNode("div", { class: "nocode-shape shape-2" }, null, -1),
3092
3324
  createElementVNode("div", { class: "nocode-shape shape-3" }, null, -1),
3093
3325
  createElementVNode("div", { class: "nocode-shape shape-4" }, null, -1)
3094
3326
  ])]);
3095
3327
  }
3096
- const DocumentLoading = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render], ["__scopeId", "data-v-d8b64b7b"]]);
3328
+ const DocumentLoading = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render], ["__scopeId", "data-v-d8b64b7b"]]);
3097
3329
  const _imports_0 = "data:image/png;base64,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";
3098
- const _hoisted_1$4 = { class: "nocode-document-layout-wrapper" };
3330
+ const _hoisted_1$3 = { class: "nocode-document-layout-wrapper" };
3099
3331
  const _hoisted_2 = {
3100
3332
  key: 0,
3101
3333
  class: "nocode-common-loading-warp"
@@ -3109,7 +3341,7 @@ const _hoisted_4 = {
3109
3341
  class: "nocode-common-loading-warp"
3110
3342
  };
3111
3343
  const _hoisted_5 = { class: "w200px text-center color-[#666]" };
3112
- const _sfc_main$6 = /* @__PURE__ */ defineComponent({
3344
+ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3113
3345
  __name: "document-layout",
3114
3346
  props: {
3115
3347
  loading: { type: Boolean },
@@ -3117,7 +3349,7 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
3117
3349
  },
3118
3350
  setup(__props) {
3119
3351
  return (_ctx, _cache) => {
3120
- return openBlock(), createElementBlock("div", _hoisted_1$4, [
3352
+ return openBlock(), createElementBlock("div", _hoisted_1$3, [
3121
3353
  __props.loading ? (openBlock(), createElementBlock("div", _hoisted_2, [
3122
3354
  createVNode(DocumentLoading)
3123
3355
  ])) : __props.hasData ? (openBlock(), createElementBlock("div", _hoisted_3, [
@@ -3535,7 +3767,7 @@ const DocumentSubTable = /* @__PURE__ */ defineComponent({
3535
3767
  }, tdAttrs, {
3536
3768
  "isEmpty": true
3537
3769
  }), {
3538
- default: () => [cellWm, tdInfo.cellValueType !== CellType.Default || tdInfo.cellWidget.props.value ? slots.widget?.({
3770
+ default: () => [cellWm, tdInfo.cellValueType !== CellType.Default || tdInfo.cellWidget.props.value || tdInfo.cellWidget.props.inlineContent?.length ? slots.widget?.({
3539
3771
  tdInfo,
3540
3772
  ...subWidgetAttrs
3541
3773
  }) : null]
@@ -3708,53 +3940,6 @@ var MaterialConsumeActionType = /* @__PURE__ */ ((MaterialConsumeActionType2) =>
3708
3940
  MaterialConsumeActionType2["CHANGE_PARSE_RULE"] = "CHANGE_PARSE_RULE";
3709
3941
  return MaterialConsumeActionType2;
3710
3942
  })(MaterialConsumeActionType || {});
3711
- const _hoisted_1$3 = {
3712
- key: 0,
3713
- class: "material-consume-action-bar"
3714
- };
3715
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
3716
- __name: "material-consume-action",
3717
- props: {
3718
- showBom: { type: Boolean, default: false },
3719
- showScanBtn: { type: Boolean, default: false },
3720
- showConfirmBtn: { type: Boolean, default: true },
3721
- rowData: {}
3722
- },
3723
- emits: ["doAction"],
3724
- setup(__props, { emit: __emit }) {
3725
- const props = __props;
3726
- const emit = __emit;
3727
- const isEditing = computed(() => {
3728
- return !props.rowData.is_confirmed_;
3729
- });
3730
- const AllMenus = Object.values(MaterialConsumeActionType).map((e) => ({
3731
- key: e,
3732
- label: $t(`sys.edhr.materialConsumeAction.${e}`)
3733
- }));
3734
- computed(() => {
3735
- return AllMenus.filter((e) => {
3736
- if (e.key === MaterialConsumeActionType.CONFIRM) {
3737
- return false;
3738
- }
3739
- return true;
3740
- });
3741
- });
3742
- const handleConfirm = () => {
3743
- emit("doAction", MaterialConsumeActionType.CONFIRM, props.rowData);
3744
- };
3745
- return (_ctx, _cache) => {
3746
- return __props.showConfirmBtn && isEditing.value ? (openBlock(), createElementBlock("div", _hoisted_1$3, [
3747
- createElementVNode("div", {
3748
- class: "sub-table-btn btn-confirm",
3749
- onClick: handleConfirm
3750
- }, [..._cache[0] || (_cache[0] = [
3751
- createElementVNode("i", { class: "iconfont icon-tijiao1" }, null, -1)
3752
- ])])
3753
- ])) : createCommentVNode("", true);
3754
- };
3755
- }
3756
- });
3757
- const MaterialConsumeAction = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-18b5f02d"]]);
3758
3943
  const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
3759
3944
  name: "NocodeMaterialConsumeTable",
3760
3945
  props: {
@@ -3808,6 +3993,7 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
3808
3993
  const {
3809
3994
  currentPageFormState
3810
3995
  } = useCurrentPageFormState();
3996
+ const selfInfoList = inject(NCB_PROVIDE.FORM_INST_LIST, []);
3811
3997
  provide(NCB_PROVIDE.MATERIAL_CONSUME_TABLE_CONTROLLER, tableController);
3812
3998
  const {
3813
3999
  field = "",
@@ -3828,12 +4014,21 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
3828
4014
  updateCalcCallback?.(dataRelationShip?.uniqueId);
3829
4015
  }
3830
4016
  });
4017
+ const currentSelfInfo = selfInfoList?.find((item) => item?.id === dataRelationShip?.key || item?.uniqueId === dataRelationShip?.uniqueId) ?? selfInfoList?.[0];
4018
+ const currentFieldDefaultData = computed(() => {
4019
+ return defaultDataMap?.[dataRelationShip?.uniqueId ?? ""] ?? {};
4020
+ });
3831
4021
  tableController.setup({
3832
4022
  tableDataRef: modelValue,
3833
4023
  widget: props.widget,
3834
4024
  formModelController,
3835
4025
  unitConversionRules,
3836
- mainFormState: currentPageFormState
4026
+ mainFormState: currentPageFormState,
4027
+ dataStatus: currentSelfInfo?.dataStatus,
4028
+ defaultRowData: renderUtils.getDefaultValueInfo({
4029
+ defaultDataMap: currentFieldDefaultData.value,
4030
+ key: field
4031
+ })
3837
4032
  });
3838
4033
  const dataInfo = computed(() => {
3839
4034
  const visibleToRealIndexMap = {};
@@ -3852,8 +4047,9 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
3852
4047
  visibleToRealIndexMap
3853
4048
  };
3854
4049
  });
3855
- const currentFieldDefaultData = computed(() => {
3856
- return defaultDataMap?.[dataRelationShip?.uniqueId ?? ""] ?? {};
4050
+ const groupRowSpans = computed(() => {
4051
+ if (dynamicIds.length !== 1) return [];
4052
+ return calcGroupRowSpans(dataInfo.value.tableData, tableController.bomEntriesValidator);
3857
4053
  });
3858
4054
  const isFormChange = computed(() => {
3859
4055
  return dataRelationShip?.formChangeStatus;
@@ -3864,66 +4060,103 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
3864
4060
  }
3865
4061
  return showDisplayStatus.value === "edit-component";
3866
4062
  });
4063
+ const markRowDeleted = (row) => {
4064
+ if (row.id_ || row.group_ && row._2DTABLE_?.some((item) => item.id_)) {
4065
+ row.deleted_ = true;
4066
+ } else {
4067
+ row.tempDeleted = true;
4068
+ }
4069
+ };
4070
+ const deleteRowAt = (row, index) => {
4071
+ recordSubtableRowDelete(dataRelationShip, field, row);
4072
+ deleteSubtableRow(field, index);
4073
+ markRowDeleted(row);
4074
+ };
3867
4075
  const handleDeleteRow = (rowData, dataIdx) => {
3868
- recordSubtableRowDelete(dataRelationShip, field, rowData);
3869
- deleteSubtableRow(field, props.start + dataIdx);
3870
- if (rowData.id_ || rowData.group_ && rowData._2DTABLE_?.some((item) => item.id_)) {
3871
- rowData.deleted_ = true;
3872
- modelValue.value = relocateDeletedRowsToEnd(modelValue.value);
4076
+ const groupId = rowData.is_confirmed_ ? rowData.bom_entry_id_ : void 0;
4077
+ if (groupId) {
4078
+ for (let index = modelValue.value.length - 1; index >= 0; index--) {
4079
+ const row = modelValue.value[index];
4080
+ if (row.deleted_ || row.bom_entry_id_ !== groupId) continue;
4081
+ deleteRowAt(row, index);
4082
+ }
3873
4083
  } else {
3874
- rowData.tempDeleted = true;
3875
- modelValue.value = modelValue.value.filter((d) => !d.tempDeleted);
4084
+ const visibleIndex = props.start + dataIdx;
4085
+ const realIndex = dataInfo.value.visibleToRealIndexMap[visibleIndex] ?? visibleIndex;
4086
+ deleteRowAt(rowData, realIndex);
3876
4087
  }
3877
- modelValue.value = [...modelValue.value];
4088
+ modelValue.value = relocateDeletedRowsToEnd(modelValue.value.filter((d) => !d.tempDeleted));
3878
4089
  };
3879
- const handleAddRow = ({
4090
+ const createDefaultRows = (rowNum, quickFillDatas, patch) => {
4091
+ return Array.from({
4092
+ length: rowNum
4093
+ }, (_, i) => {
4094
+ const row = transformUtils.addSubTableRowItem({
4095
+ defaultData: currentFieldDefaultData.value,
4096
+ quickFillData: quickFillDatas?.[i],
4097
+ subFieldId: field,
4098
+ isRowSubTable2d,
4099
+ childInitRowLen
4100
+ });
4101
+ row.is_confirmed_ = false;
4102
+ patch?.(row);
4103
+ return row;
4104
+ });
4105
+ };
4106
+ const insertRowsAt = (insertIndex, rows) => {
4107
+ if (!rows.length) return;
4108
+ insertSubtableRows(field, insertIndex, rows.length);
4109
+ modelValue.value.splice(insertIndex, 0, ...rows);
4110
+ modelValue.value = relocateDeletedRowsToEnd(modelValue.value);
4111
+ recordSubtableRowAdd(dataRelationShip, field, rows);
4112
+ updateCalcCallback?.(dataRelationShip?.uniqueId);
4113
+ };
4114
+ const resolveRealIndex = (index) => dataInfo.value.visibleToRealIndexMap[props.start + index];
4115
+ const handleAddRowForGroup = ({
3880
4116
  index,
3881
- position = "after",
3882
- rowNum = 1,
3883
- actionType,
3884
4117
  rowData,
4118
+ rowNum = 1,
3885
4119
  quickFillDatas
3886
4120
  }) => {
3887
- if (!isFormChange.value && tableController.hasEditingRow()) {
3888
- return;
3889
- }
3890
- const newRowsData = actionType === "copyRow" ? [cloneDeep(omit(rowData, ["id_", FRONT_ROW_KEY]))] : Array.from({
3891
- length: rowNum
3892
- }, (_, index2) => transformUtils.addSubTableRowItem({
3893
- defaultData: currentFieldDefaultData.value,
3894
- quickFillData: quickFillDatas?.[index2],
3895
- subFieldId: field,
3896
- isRowSubTable2d,
3897
- childInitRowLen
4121
+ insertRowsAt(resolveRealIndex(index) + 1, createDefaultRows(rowNum, quickFillDatas, (r) => {
4122
+ if (rowData.bom_entry_id_) r.bom_entry_id_ = rowData.bom_entry_id_;
3898
4123
  }));
3899
- newRowsData.forEach((rowData2) => {
3900
- rowData2.is_confirmed_ = false;
3901
- });
3902
- const visibleIndex = props.start + index;
3903
- const realIndex = dataInfo.value.visibleToRealIndexMap[visibleIndex];
3904
- let insertIndex = 0;
3905
- switch (position) {
3906
- case "before":
3907
- insertIndex = realIndex;
3908
- break;
3909
- case "after":
3910
- insertIndex = realIndex + 1;
3911
- break;
3912
- case "last":
3913
- insertIndex = modelValue.value.length;
3914
- break;
3915
- }
3916
- if (actionType === "currentRow") {
3917
- const firstData = newRowsData.shift();
3918
- merge(rowData, omit(firstData, ["id_", FRONT_ROW_KEY]));
4124
+ };
4125
+ const handleAddGroup = async ({
4126
+ index,
4127
+ rowData,
4128
+ quickFillDatas
4129
+ }) => {
4130
+ const {
4131
+ bomEntriesValidator,
4132
+ enableSequenceLoading,
4133
+ actualTableData,
4134
+ error
4135
+ } = tableController;
4136
+ if (enableSequenceLoading) {
4137
+ const editing = bomEntriesValidator.findSequenceBomEntry(actualTableData);
4138
+ if (editing) {
4139
+ try {
4140
+ await bomEntriesValidator.validateCurrentGroupForSwitch(actualTableData, editing);
4141
+ setGroupEditState(actualTableData, editing, false);
4142
+ } catch (e) {
4143
+ if (e?.message) error(e.message);
4144
+ return;
4145
+ }
4146
+ }
3919
4147
  }
3920
- if (newRowsData.length > 0) {
3921
- insertSubtableRows(field, insertIndex, newRowsData.length);
3922
- modelValue.value.splice(insertIndex, 0, ...newRowsData);
3923
- modelValue.value = relocateDeletedRowsToEnd(modelValue.value);
3924
- recordSubtableRowAdd(dataRelationShip, field, newRowsData);
4148
+ const entryIdx = bomEntriesValidator.resolveEntryIndex(rowData);
4149
+ const util = entryIdx >= 0 ? bomEntriesValidator.bomEntryValidators[entryIdx] : void 0;
4150
+ let groupLast = -1;
4151
+ if (util) {
4152
+ modelValue.value.forEach((r, i) => {
4153
+ if (isRowInBomGroup(r, util)) {
4154
+ groupLast = i;
4155
+ }
4156
+ });
3925
4157
  }
3926
- updateCalcCallback?.(dataRelationShip?.uniqueId);
4158
+ if (groupLast < 0) groupLast = resolveRealIndex(index);
4159
+ insertRowsAt(groupLast + 1, createDefaultRows(1, quickFillDatas));
3927
4160
  };
3928
4161
  const handleAction = (action, rowData) => {
3929
4162
  switch (action) {
@@ -3943,7 +4176,13 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
3943
4176
  break;
3944
4177
  }
3945
4178
  };
3946
- const getNewTdInfo = (tdInfo, rowData) => {
4179
+ const getNewTdInfo = (tdInfo, rowData, rowIndex) => {
4180
+ if (!tdInfo.cellHidden && tdInfo.cellWidget?.props?.type === "serialnumber") {
4181
+ const cloneData2 = cloneDeep(tdInfo);
4182
+ cloneData2.cellWidget.props.groupSerialnumber = true;
4183
+ cloneData2.cellWidget.props.groupOrderIndex = tableController.bomEntriesValidator.resolveGroupOrderIndex(rowData, tableController.actualTableData);
4184
+ return cloneData2;
4185
+ }
3947
4186
  if (tdInfo.cellHidden || !tdInfo?.cellWidget?.props?.field) {
3948
4187
  return tdInfo;
3949
4188
  }
@@ -3955,11 +4194,20 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
3955
4194
  if (tdInfo.cellWidget.props.field === "material_no_") {
3956
4195
  cloneData.cellWidget.props.newSpecificConfig.newOptions = [];
3957
4196
  merge(cloneData.cellWidget.props.newSpecificConfig, {
3958
- newQueryData: {
3959
- "product_id_.versionIn": rowData.product_id_ ? [rowData.product_id_.split(":").pop()] : null
3960
- }
4197
+ newQueryData: tableController.getMaterialNoQueryForRow(rowData, rowIndex)
3961
4198
  });
3962
4199
  }
4200
+ if (fieldKey === "product_id_") {
4201
+ cloneData.cellWidget.props.needWatchOpen = true;
4202
+ const rowQuery = tableController.getProductQueryForRow(rowData, rowIndex);
4203
+ if (rowQuery) {
4204
+ cloneData.cellWidget.props.newSpecificConfig.newOptions = [];
4205
+ cloneData.cellWidget.props.newSpecificConfig.newQueryData = {
4206
+ ...cloneData.cellWidget.props.newSpecificConfig?.newQueryData ?? {},
4207
+ ...rowQuery
4208
+ };
4209
+ }
4210
+ }
3963
4211
  if (fieldKey === "qty_uom_id_" || fieldKey === "qty_required_uom_id_") {
3964
4212
  cloneData.cellWidget.props.quickSearchField = ["name_.like", "code_.like"];
3965
4213
  cloneData.cellWidget.props.quickSearchExp = "OR(name_.like,code_.like)";
@@ -3979,70 +4227,89 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
3979
4227
  }
3980
4228
  return cloneData;
3981
4229
  };
3982
- const handleMenuClick = (rowData, dataIdx) => ({
4230
+ const handleMenuClick = (rowData, dataIdx) => async ({
3983
4231
  key,
3984
4232
  actionValue
3985
4233
  }) => {
3986
4234
  switch (key) {
3987
4235
  case "rowEdit":
3988
- tableController.editRow(rowData);
3989
- break;
3990
- case "insertRowBefore":
3991
- handleAddRow({
3992
- index: dataIdx,
3993
- position: "before",
3994
- rowNum: actionValue?.upRowNum || 1,
3995
- quickFillDatas: actionValue?.data,
3996
- actionType: "prevRow",
3997
- rowData
3998
- });
4236
+ await tableController.editRow(rowData);
3999
4237
  break;
4238
+ // case 'insertRowBefore':
4239
+ // handleAddRow({
4240
+ // index: dataIdx,
4241
+ // position: 'before',
4242
+ // rowNum: actionValue?.upRowNum || 1,
4243
+ // quickFillDatas: actionValue?.data,
4244
+ // actionType: 'prevRow',
4245
+ // rowData,
4246
+ // });
4247
+ // break;
4000
4248
  case "insert1RowAfter":
4001
4249
  case "insertRowAfter":
4002
- handleAddRow({
4003
- index: dataIdx,
4004
- position: "after",
4005
- rowNum: actionValue?.downRowNum || 1,
4006
- quickFillDatas: actionValue?.data,
4007
- actionType: "nextRow",
4008
- rowData
4009
- });
4010
- break;
4011
- case "insertRowCurrent":
4012
- handleAddRow({
4013
- index: dataIdx,
4014
- position: "after",
4015
- rowNum: actionValue?.downRowNum || 1,
4016
- quickFillDatas: actionValue?.data,
4017
- actionType: "currentRow",
4018
- rowData
4019
- });
4020
- break;
4021
- case "copyRowAfter":
4022
- handleAddRow({
4250
+ handleAddRowForGroup({
4023
4251
  index: dataIdx,
4024
- position: "after",
4025
4252
  rowNum: actionValue?.downRowNum || 1,
4026
4253
  quickFillDatas: actionValue?.data,
4027
- actionType: "copyRow",
4028
4254
  rowData
4029
4255
  });
4030
- tableController.updateRowConsumed();
4031
4256
  break;
4032
- case "copyRow2Last":
4033
- handleAddRow({
4257
+ case "insert1GroupAfter":
4258
+ handleAddGroup({
4034
4259
  index: dataIdx,
4035
- position: "last",
4036
4260
  rowNum: actionValue?.downRowNum || 1,
4037
4261
  quickFillDatas: actionValue?.data,
4038
- actionType: "copyRow",
4039
4262
  rowData
4040
4263
  });
4041
- tableController.updateRowConsumed();
4042
4264
  break;
4265
+ // case 'insertRowCurrent':
4266
+ // handleAddRow({
4267
+ // index: dataIdx,
4268
+ // position: 'after',
4269
+ // rowNum: actionValue?.downRowNum || 1,
4270
+ // quickFillDatas: actionValue?.data,
4271
+ // actionType: 'currentRow',
4272
+ // rowData,
4273
+ // });
4274
+ // break;
4275
+ // case 'copyRowAfter':
4276
+ // handleAddRow({
4277
+ // index: dataIdx,
4278
+ // position: 'after',
4279
+ // rowNum: actionValue?.downRowNum || 1,
4280
+ // quickFillDatas: actionValue?.data,
4281
+ // actionType: 'copyRow',
4282
+ // rowData,
4283
+ // });
4284
+ // // 更新计算已消耗数量
4285
+ // tableController.updateRowConsumed();
4286
+ // break;
4287
+ // case 'copyRow2Last':
4288
+ // handleAddRow({
4289
+ // index: dataIdx,
4290
+ // position: 'last',
4291
+ // rowNum: actionValue?.downRowNum || 1,
4292
+ // quickFillDatas: actionValue?.data,
4293
+ // actionType: 'copyRow',
4294
+ // rowData,
4295
+ // });
4296
+ // // 更新计算已消耗数量
4297
+ // tableController.updateRowConsumed();
4298
+ // break;
4043
4299
  case "deleteRowCurrent":
4044
- handleDeleteRow(rowData, dataIdx);
4045
- tableController.updateRowConsumed();
4300
+ Modal.confirm({
4301
+ width: 316,
4302
+ centered: true,
4303
+ class: "confirm-before-delete-modal",
4304
+ icon: h("i", {
4305
+ class: "iconfont icon-jinggao"
4306
+ }),
4307
+ content: "是否确认删除?",
4308
+ onOk() {
4309
+ handleDeleteRow(rowData, dataIdx);
4310
+ tableController.updateDerivedQtyFields();
4311
+ }
4312
+ });
4046
4313
  break;
4047
4314
  default:
4048
4315
  handleAction(key, rowData);
@@ -4054,39 +4321,66 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
4054
4321
  showScanBtn,
4055
4322
  showEditBtn,
4056
4323
  dataIdx,
4057
- dynHeight
4324
+ dynHeight,
4325
+ showInsert1RowBtn
4058
4326
  }) => {
4059
- const menus = [{
4060
- type: SubTableActionMenuTypeEnum.SUBTITLE,
4061
- label: "业务操作"
4062
- }, showScanBtn ? getMenuByAction(SubTableActionEnum.SCAN) : void 0, tableController.actualBomEntries?.length ? getMenuByAction(SubTableActionEnum.VIEW_BOM) : void 0, getMenuByAction(SubTableActionEnum.CHANGE_PARSE_RULE), {
4063
- type: SubTableActionMenuTypeEnum.DIVIDER
4064
- }, {
4065
- type: SubTableActionMenuTypeEnum.SUBTITLE,
4066
- label: "行编辑"
4067
- }, showEditBtn ? getMenuByAction(SubTableActionEnum.RowEdit) : void 0, getMenuByAction(SubTableActionEnum.Insert1RowAfter), getCopySubMenu(), ...showDelBtn ? [{
4068
- type: SubTableActionMenuTypeEnum.DIVIDER
4069
- }, getMenuByAction(SubTableActionEnum.DeleteRowCurrent)] : []].filter(Boolean);
4327
+ const menus = [
4328
+ {
4329
+ type: SubTableActionMenuTypeEnum.SUBTITLE,
4330
+ label: "业务操作"
4331
+ },
4332
+ showScanBtn ? getMenuByAction(SubTableActionEnum.SCAN) : void 0,
4333
+ // tableController.actualBomEntries?.length
4334
+ // ? getMenuByAction(SubTableActionEnum.VIEW_BOM)
4335
+ // : undefined,
4336
+ // getMenuByAction(SubTableActionEnum.CHANGE_PARSE_RULE),
4337
+ {
4338
+ type: SubTableActionMenuTypeEnum.DIVIDER
4339
+ },
4340
+ {
4341
+ type: SubTableActionMenuTypeEnum.SUBTITLE,
4342
+ label: "行编辑"
4343
+ },
4344
+ showEditBtn ? getMenuByAction(SubTableActionEnum.RowEdit) : void 0,
4345
+ showInsert1RowBtn ? getMenuByAction(SubTableActionEnum.Insert1RowAfter) : void 0,
4346
+ getMenuByAction(SubTableActionEnum.Insert1GroupAfter),
4347
+ // getCopySubMenu(),
4348
+ ...showDelBtn ? [{
4349
+ type: SubTableActionMenuTypeEnum.DIVIDER
4350
+ }, getMenuByAction(SubTableActionEnum.DeleteRowCurrent)] : []
4351
+ ].filter(Boolean);
4352
+ const realRowIndex = dataIdx !== -1 ? resolveRealIndex(dataIdx) : void 0;
4070
4353
  return createVNode("tr", {
4071
4354
  "key": trKey,
4072
4355
  "height": dynHeight || trData.props.height
4073
4356
  }, [trData.nextIds.map((tdId) => {
4074
- const tdInfo = getNewTdInfo(props.widgetCenter[tdId], rowData);
4357
+ const rawTdInfo = props.widgetCenter[tdId];
4358
+ if (dataIdx !== -1 && groupRowSpans.value.length && isGroupMergeCell(rawTdInfo) && groupRowSpans.value[dataIdx] === 0) {
4359
+ return null;
4360
+ }
4361
+ const tdInfo = getNewTdInfo(rawTdInfo, rowData, realRowIndex);
4362
+ const groupRowspan = dataIdx !== -1 && groupRowSpans.value.length && isGroupMergeCell(tdInfo) && groupRowSpans.value[dataIdx] > 1 ? groupRowSpans.value[dataIdx] : void 0;
4075
4363
  const tdAttrs = {
4076
4364
  key: tdId,
4077
4365
  id: tdId,
4078
4366
  hidden: tdInfo.cellHidden,
4079
4367
  borderAttrs: tdInfo.props.sourceBorderAttrs,
4080
- autoMerge: tdInfo.fillDirection === "x" ? tdInfo.xAutoMerge : tdInfo.autoMerge,
4368
+ autoMerge: groupRowspan ? false : tdInfo.fillDirection === "x" ? tdInfo.xAutoMerge : tdInfo.autoMerge,
4081
4369
  fillDirection: tdInfo.fillDirection,
4082
4370
  ...pick(tdInfo.props, ["rowspan", "colspan", "class"])
4083
4371
  };
4372
+ if (groupRowspan) {
4373
+ tdAttrs.rowspan = groupRowspan;
4374
+ }
4084
4375
  const realTdAttrInfo = props.subInfo.mergeBlock?.[tdId];
4085
4376
  if (realTdAttrInfo) {
4086
4377
  Object.assign(tdAttrs, {
4087
4378
  ...pick(realTdAttrInfo, ["rowspan", "colspan", "borderAttrs"]),
4088
4379
  hidden: false
4089
4380
  });
4381
+ if (groupRowspan) {
4382
+ tdAttrs.rowspan = groupRowspan;
4383
+ }
4090
4384
  }
4091
4385
  if (tdInfo.cellValueType) {
4092
4386
  if (props.isMobile) {
@@ -4117,7 +4411,7 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
4117
4411
  }, tdAttrs, {
4118
4412
  "isEmpty": true
4119
4413
  }), {
4120
- default: () => [tdInfo.cellValueType !== CellType.Default || tdInfo.cellWidget.props.value ? slots.widget?.({
4414
+ default: () => [tdInfo.cellValueType !== CellType.Default || tdInfo.cellWidget.props.value || tdInfo.cellWidget.props.inlineContent?.length ? slots.widget?.({
4121
4415
  tdInfo,
4122
4416
  ...subWidgetAttrs
4123
4417
  }) : null]
@@ -4130,6 +4424,7 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
4130
4424
  "isEmpty": true
4131
4425
  }), null);
4132
4426
  }
4427
+ return null;
4133
4428
  }), showAction.value && showActionMenu && createVNode("div", {
4134
4429
  "class": "sub-table-action-bar"
4135
4430
  }, [slots.subAction?.({
@@ -4137,11 +4432,7 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
4137
4432
  subTableFieldId: field,
4138
4433
  mobileTdIdGroups: dataRelationShip?.mobileTdIdGroups,
4139
4434
  handleMenuClick: handleMenuClick(rowData, dataIdx)
4140
- }), createVNode(MaterialConsumeAction, {
4141
- "showConfirmBtn": !isFormChange.value,
4142
- "rowData": rowData,
4143
- "onDoAction": handleAction
4144
- }, null)])]);
4435
+ })])]);
4145
4436
  };
4146
4437
  return () => createVNode("div", {
4147
4438
  "class": "cmp-sub-table"
@@ -4154,7 +4445,6 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
4154
4445
  "width": cw
4155
4446
  }, null))]), createVNode("tbody", null, [props.subInfo.containerIds.map((trId) => {
4156
4447
  const trInfo = props.widgetCenter[trId];
4157
- console.log("trInfo", trInfo);
4158
4448
  if (trInfo.props.identifier !== "dynamicTr") {
4159
4449
  const dynHeight = props.subInfo.dynamicRowHeights?.[trId];
4160
4450
  return renderTr2Td(trId, trInfo, realFormState.value, {
@@ -4165,17 +4455,16 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
4165
4455
  });
4166
4456
  }
4167
4457
  if (trId === lastDynamicId) {
4168
- const lastDataIdx = dataInfo.value.tableData.length - 1;
4458
+ dataInfo.value.tableData.length - 1;
4169
4459
  return dataInfo.value.tableData.map((data, dataIdx) => {
4170
4460
  const stableRowKey = getRowId(data);
4171
4461
  return dynamicIds.map((rowId, rowIdx) => {
4172
4462
  const isLastDynRow = rowIdx === lastDynRowIdx;
4173
- const isLast = dataIdx === lastDataIdx && isLastDynRow;
4174
- const showDelBtn = dataInfo.value.hasSubData && isLastDynRow && // 开启了顺序投料时,只有最后一行可以删除
4175
- (tableController.enableSequenceLoading ? isLast : true);
4176
- const showScanBtn = isLast;
4463
+ const showDelBtn = dataInfo.value.hasSubData && isLastDynRow;
4464
+ const showScanBtn = isLastDynRow;
4177
4465
  const showActionMenu = isLastDynRow;
4178
- const showEditBtn = !isFormChange.value && (tableController.enableSequenceLoading ? isLast : true) && data.is_confirmed_;
4466
+ const showEditBtn = !isFormChange.value && data.is_confirmed_;
4467
+ const showInsert1RowBtn = !isFormChange.value && !data.is_confirmed_;
4179
4468
  const row = props.widgetCenter[rowId];
4180
4469
  const dynHeight = props.subInfo.dynamicRowHeights?.[rowId]?.[dataIdx];
4181
4470
  return renderTr2Td(`${stableRowKey}_${rowIdx}`, row, data, {
@@ -4184,7 +4473,8 @@ const MaterialConsumeTable = /* @__PURE__ */ defineComponent({
4184
4473
  showScanBtn,
4185
4474
  showEditBtn,
4186
4475
  dataIdx,
4187
- dynHeight
4476
+ dynHeight,
4477
+ showInsert1RowBtn
4188
4478
  });
4189
4479
  });
4190
4480
  });
@@ -4350,7 +4640,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
4350
4640
  show: props.showEditBtn,
4351
4641
  type: "action",
4352
4642
  key: SubTableActionEnum.RowEdit,
4353
- label: "重新编辑当前行",
4643
+ label: "编辑",
4354
4644
  icon: "icon-zhongxinbianjidangqianhang"
4355
4645
  },
4356
4646
  {
@@ -4553,7 +4843,7 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
4553
4843
  };
4554
4844
  }
4555
4845
  });
4556
- const SubTableAction = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-e0624e4c"]]);
4846
+ const SubTableAction = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-01ca4702"]]);
4557
4847
  const _sfc_main$2 = /* @__PURE__ */ defineComponent({
4558
4848
  __name: "fixed-table-action",
4559
4849
  props: {
@@ -4666,12 +4956,7 @@ const DocumentPaper = /* @__PURE__ */ defineComponent({
4666
4956
  const subTableCoreFactory = computed(() => subTableCoreFactoryMap.value?.[props.basicInfo?.uniqueId]);
4667
4957
  const filledFixedTableKeys = ref([]);
4668
4958
  const fixedTables = computed(() => {
4669
- const info = props.selfInfoList?.[0];
4670
- if (!info) {
4671
- return [];
4672
- }
4673
- const designer = JSON.parse(info.designerJson || "{}");
4674
- return designer.sheets?.[0]?.paper?.fixedTables || designer.fixedTables || [];
4959
+ return props.widgetCenter.paper?.props.fixedTables || [];
4675
4960
  });
4676
4961
  const fixedTableInfoMap = computed(() => {
4677
4962
  const {
@@ -4939,7 +5224,7 @@ const DocumentPaper = /* @__PURE__ */ defineComponent({
4939
5224
  }, tdAttrs, {
4940
5225
  "isEmpty": true
4941
5226
  }), {
4942
- default: () => tdInfo.cellValueType !== CellType.Default || tdInfo.cellWidget.props.value ? slots.widget?.({
5227
+ default: () => tdInfo.cellValueType !== CellType.Default || tdInfo.cellWidget.props.value || tdInfo.cellWidget.props.inlineContent?.length ? slots.widget?.({
4943
5228
  tdInfo,
4944
5229
  ...widgetAttrs,
4945
5230
  dynamicConfig
@@ -5126,28 +5411,27 @@ export {
5126
5411
  FixedQuickFillModal as F,
5127
5412
  InstanceStatusValues as I,
5128
5413
  MaterialConsumptionPatternEnum as M,
5129
- SubTableCore as S,
5130
- _sfc_main$6 as _,
5131
- useFormTmplConfig as a,
5132
- useStyles as b,
5133
- useDependency as c,
5134
- useValidator as d,
5135
- DocumentPaper as e,
5136
- DynamicTableAction as f,
5137
- MaterialConsumeTableController as g,
5138
- SubTableActionMenuTypeEnum as h,
5139
- getMenuByAction as i,
5140
- SubTableActionEnum as j,
5141
- getCopySubMenu as k,
5142
- getInsertSubMenu as l,
5143
- useMaterialBalance as m,
5144
- commonUtils as n,
5145
- DeviceConnector as o,
5146
- DocumentLoading as p,
5147
- DynamicQuickFillModal as q,
5148
- FormTmplConfigController as r,
5149
- MCDataUtil as s,
5150
- useOnlineFormActionButton as t,
5151
- useOnlineFormTransformField2Component as u,
5414
+ OCR_MODEL_PRECISION_ENUM_KEY as O,
5415
+ RequiredQtyCalcRule as R,
5416
+ ScanParamType as S,
5417
+ _sfc_main$5 as _,
5418
+ useStyles as a,
5419
+ useValidator as b,
5420
+ DocumentPaper as c,
5421
+ DynamicTableAction as d,
5422
+ MaterialConsumeTableController as e,
5423
+ SubTableCore as f,
5424
+ SubTableActionMenuTypeEnum as g,
5425
+ getMenuByAction as h,
5426
+ SubTableActionEnum as i,
5427
+ getCopySubMenu as j,
5428
+ getInsertSubMenu as k,
5429
+ useMaterialBalance as l,
5430
+ DeviceConnector as m,
5431
+ DocumentLoading as n,
5432
+ DynamicQuickFillModal as o,
5433
+ FormTmplConfigController as p,
5434
+ MCDataUtil as q,
5435
+ useFormTmplConfig as u,
5152
5436
  validate as v
5153
5437
  };