cloud-web-corejs 1.0.276 → 1.0.277

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 (305) hide show
  1. package/package.json +28 -24
  2. package/src/App.vue +73 -71
  3. package/src/api/user.js +21 -0
  4. package/src/components/baseArea/index.vue +82 -27
  5. package/src/components/baseTabs/mixins.js +5 -1
  6. package/src/components/luckysheet/dialog.vue +1 -1
  7. package/src/components/micro-view-host/contract.js +66 -0
  8. package/src/components/micro-view-host/index.vue +148 -0
  9. package/src/components/table/tableForm.vue +16 -5
  10. package/src/components/table/tableFormMixin.js +35 -7
  11. package/src/components/vb-tabs/x-tabs.vue +167 -143
  12. package/src/components/wf/content.vue +14 -0
  13. package/src/components/wf/content2.vue +4 -2
  14. package/src/components/wf/wf.js +74 -23
  15. package/src/components/wf/wfActionDropdown.vue +85 -0
  16. package/src/components/wf/wfActionItems.js +136 -0
  17. package/src/components/wf/wfAutoConfirm.js +55 -0
  18. package/src/components/wf/wfButtonName.js +60 -0
  19. package/src/components/wf/wfUserRange.js +53 -0
  20. package/src/components/wf/wfUtil.js +373 -295
  21. package/src/components/xform/XFormTabContainer//346/226/260/345/242/236/351/241/265/347/255/276/346/250/241/345/274/217-/346/234/200/347/273/210/345/256/236/347/216/260.md +195 -0
  22. package/src/components/xform/docs/2026-07 table/344/270/216excelExport/344/277/256/345/244/215/345/217/212/345/257/274/345/207/272/344/274/230/345/214/226.md" +57 -0
  23. package/src/components/xform/docs/2026-07 /346/216/222/346/237/245/344/277/256/345/244/215/350/256/260/345/275/225.md" +73 -0
  24. package/src/components/xform/docs/autocomplete /350/207/252/345/212/250/345/256/214/346/210/220/347/273/204/344/273/266/350/257/264/346/230/216.md" +126 -0
  25. package/src/components/xform/docs//345/257/271/346/257/224/345/212/237/350/203/275/350/220/275/345/234/260/346/226/271/346/241/210.md +986 -0
  26. package/src/components/xform/docs//346/225/260/346/215/256/350/241/250/346/240/274/345/212/250/346/200/201/345/210/227 JSON /350/257/264/346/230/216.md" +657 -0
  27. package/src/components/xform/docs//346/240/221/350/241/250rowField/346/224/266/346/225/233-/350/220/275/345/234/260/346/226/207/346/241/243.md +1427 -0
  28. package/src/components/xform/form-designer/designer.js +2085 -2025
  29. package/src/components/xform/form-designer/form-widget/container-widget/containerMixin.js +9 -11
  30. package/src/components/xform/form-designer/form-widget/container-widget/data-table-mixin.js +76 -75
  31. package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +10 -4
  32. package/src/components/xform/form-designer/form-widget/container-widget/detail-plain-widget.vue +76 -0
  33. package/src/components/xform/form-designer/form-widget/container-widget/detail-widget.vue +59 -5
  34. package/src/components/xform/form-designer/form-widget/dialog/fileReferenceDialog.vue +38 -17
  35. package/src/components/xform/form-designer/form-widget/dialog/formDialog.vue +138 -13
  36. package/src/components/xform/form-designer/form-widget/dialog/formFieldDialog.vue +1 -1
  37. package/src/components/xform/form-designer/form-widget/dialog/importDialogMixin.js +1774 -1772
  38. package/src/components/xform/form-designer/form-widget/dialog/searchFormDialog.vue +2 -3
  39. package/src/components/xform/form-designer/form-widget/dialog/vabSearchDialog.vue +1 -1
  40. package/src/components/xform/form-designer/form-widget/field-widget/a-link-widget.vue +66 -53
  41. package/src/components/xform/form-designer/form-widget/field-widget/baseAttachment-widget.vue +287 -214
  42. package/src/components/xform/form-designer/form-widget/field-widget/button-widget.vue +76 -66
  43. package/src/components/xform/form-designer/form-widget/field-widget/cascader-widget.vue +208 -124
  44. package/src/components/xform/form-designer/form-widget/field-widget/census-widget.vue +3 -9
  45. package/src/components/xform/form-designer/form-widget/field-widget/copy_button-widget.vue +11 -2
  46. package/src/components/xform/form-designer/form-widget/field-widget/date-range-widget.vue +7 -6
  47. package/src/components/xform/form-designer/form-widget/field-widget/date-widget.vue +43 -19
  48. package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +680 -372
  49. package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +879 -763
  50. package/src/components/xform/form-designer/form-widget/field-widget/mixins/date-limit-mixin.js +17 -2
  51. package/src/components/xform/form-designer/form-widget/field-widget/mixins/echart-bar-mixin.js +3 -9
  52. package/src/components/xform/form-designer/form-widget/field-widget/mixins/echart-category-mixin.js +3 -9
  53. package/src/components/xform/form-designer/form-widget/field-widget/mixins/echart-pie-mixin.js +3 -9
  54. package/src/components/xform/form-designer/form-widget/field-widget/mixins/relative-default-mixin.js +107 -0
  55. package/src/components/xform/form-designer/form-widget/field-widget/mixins/relativeDateUtil.js +321 -0
  56. package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js +77 -0
  57. package/src/components/xform/form-designer/form-widget/field-widget/mixins/vabsearch-mixin.js +13 -0
  58. package/src/components/xform/form-designer/form-widget/field-widget/number-widget.vue +13 -8
  59. package/src/components/xform/form-designer/form-widget/field-widget/project-tag-widget.vue +4 -9
  60. package/src/components/xform/form-designer/form-widget/field-widget/save_submit_wf_button-widget.vue +3 -0
  61. package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +120 -120
  62. package/src/components/xform/form-designer/form-widget/field-widget/static-content-wrapper.vue +4 -0
  63. package/src/components/xform/form-designer/form-widget/field-widget/status-widget.vue +11 -0
  64. package/src/components/xform/form-designer/form-widget/field-widget/switch-widget.vue +9 -1
  65. package/src/components/xform/form-designer/form-widget/field-widget/tempStorage-widget.vue +1 -1
  66. package/src/components/xform/form-designer/form-widget/field-widget/text-widget.vue +7 -3
  67. package/src/components/xform/form-designer/form-widget/field-widget/time-range-widget.vue +4 -2
  68. package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +36 -5
  69. package/src/components/xform/form-designer/form-widget/field-widget/vabUpload-widget.vue +338 -374
  70. package/src/components/xform/form-designer/form-widget/index.vue +6 -1
  71. package/src/components/xform/form-designer/form-widget/indexMixin.js +29 -25
  72. package/src/components/xform/form-designer/index.vue +194 -191
  73. package/src/components/xform/form-designer/indexMixin.js +860 -847
  74. package/src/components/xform/form-designer/setting-panel/dataSource-setting.vue +397 -397
  75. package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +602 -601
  76. package/src/components/xform/form-designer/setting-panel/form-setting.vue +1790 -1483
  77. package/src/components/xform/form-designer/setting-panel/index.vue +2 -7
  78. package/src/components/xform/form-designer/setting-panel/indexMixin.js +370 -335
  79. package/src/components/xform/form-designer/setting-panel/option-items-setting.vue +585 -544
  80. package/src/components/xform/form-designer/setting-panel/property-editor/a-link-editor.vue +1 -1
  81. package/src/components/xform/form-designer/setting-panel/property-editor/a-text-editor.vue +1 -1
  82. package/src/components/xform/form-designer/setting-panel/property-editor/alignType-editor.vue +1 -1
  83. package/src/components/xform/form-designer/setting-panel/property-editor/buttonIcon-editor.vue +14 -15
  84. package/src/components/xform/form-designer/setting-panel/property-editor/censusClass-editor.vue +1 -1
  85. package/src/components/xform/form-designer/setting-panel/property-editor/colorClass-editor.vue +1 -1
  86. package/src/components/xform/form-designer/setting-panel/property-editor/commonAttributeEnabled-editor.vue +3 -3
  87. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/columnRenderDialog.vue +124 -125
  88. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +1151 -957
  89. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail/detail-editor.vue +96 -74
  90. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail-plain/detail-plain-editor.vue +75 -0
  91. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/colHeight-editor.vue +1 -1
  92. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/gutter-editor.vue +14 -13
  93. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-height-editor.vue +1 -1
  94. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-offset-editor.vue +1 -1
  95. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-pull-editor.vue +1 -1
  96. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-push-editor.vue +1 -1
  97. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-span-editor.vue +4 -4
  98. package/src/components/xform/form-designer/setting-panel/property-editor/container-h5-card/h5-card-editor.vue +124 -124
  99. package/src/components/xform/form-designer/setting-panel/property-editor/container-list-h5/list-h5-editor.vue +26 -31
  100. package/src/components/xform/form-designer/setting-panel/property-editor/container-panel/height-editor.vue +1 -1
  101. package/src/components/xform/form-designer/setting-panel/property-editor/container-panel/width-editor.vue +1 -1
  102. package/src/components/xform/form-designer/setting-panel/property-editor/container-tab/tab-customClass-editor.vue +119 -119
  103. package/src/components/xform/form-designer/setting-panel/property-editor/container-tab/tabClass-editor.vue +45 -45
  104. package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +340 -342
  105. package/src/components/xform/form-designer/setting-panel/property-editor/container-table-cell/cellHeight-editor.vue +1 -1
  106. package/src/components/xform/form-designer/setting-panel/property-editor/container-table-cell/cellWidth-editor.vue +1 -1
  107. package/src/components/xform/form-designer/setting-panel/property-editor/container-tree/tree-customClass-editor.vue +2 -2
  108. package/src/components/xform/form-designer/setting-panel/property-editor/container-tree-pane/tree-pane-editor.vue +1 -1
  109. package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/cancelButtonLabel-editor.vue +1 -1
  110. package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/okButtonLabel-editor.vue +1 -1
  111. package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/title-editor.vue +1 -1
  112. package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/width-editor.vue +1 -1
  113. package/src/components/xform/form-designer/setting-panel/property-editor/containerClass-editor.vue +1 -1
  114. package/src/components/xform/form-designer/setting-panel/property-editor/customClass-editor.vue +1 -1
  115. package/src/components/xform/form-designer/setting-panel/property-editor/defaultValue-editor.vue +1 -1
  116. package/src/components/xform/form-designer/setting-panel/property-editor/descriptionsItems-editor.vue +4 -4
  117. package/src/components/xform/form-designer/setting-panel/property-editor/downloadButtonFlag-editor.vue +3 -3
  118. package/src/components/xform/form-designer/setting-panel/property-editor/dropdownFlag-editor.vue +6 -2
  119. package/src/components/xform/form-designer/setting-panel/property-editor/dsName-editor.vue +1 -1
  120. package/src/components/xform/form-designer/setting-panel/property-editor/echartHeight-editor.vue +1 -1
  121. package/src/components/xform/form-designer/setting-panel/property-editor/endPlaceholder-editor.vue +1 -1
  122. package/src/components/xform/form-designer/setting-panel/property-editor/field-accessUrl/accessUrl-editor.vue +2 -2
  123. package/src/components/xform/form-designer/setting-panel/property-editor/field-area-select/areaDataType-editor.vue +1 -1
  124. package/src/components/xform/form-designer/setting-panel/property-editor/field-area-select/areaMinLevel-editor.vue +50 -50
  125. package/src/components/xform/form-designer/setting-panel/property-editor/field-area-select/areaName-editor.vue +1 -1
  126. package/src/components/xform/form-designer/setting-panel/property-editor/field-autocomplete/autocomplete-vabSearchName-editor.vue +7 -7
  127. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/addTableData-event-editor.vue +84 -85
  128. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/button-type-editor.vue +1 -1
  129. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/clickBindActions.js +262 -0
  130. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/clickBindEvent-editor.vue +97 -88
  131. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/form-host-event-editor.vue +188 -0
  132. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/icon-editor.vue +14 -15
  133. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +27 -10
  134. package/src/components/xform/form-designer/setting-panel/property-editor/field-cascader/checkStrictly-editor.vue +11 -13
  135. package/src/components/xform/form-designer/setting-panel/property-editor/field-common/keyName-editor.vue +74 -67
  136. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-dateLimit-editor.vue +27 -5
  137. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-defaultValue-editor.vue +35 -18
  138. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-format-editor.vue +1 -1
  139. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-type-editor.vue +1 -1
  140. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-valueFormat-editor.vue +1 -1
  141. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultTime-editor.vue +1 -1
  142. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultValue-editor.vue +35 -18
  143. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-format-editor.vue +1 -1
  144. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-type-editor.vue +1 -1
  145. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-valueFormat-editor.vue +1 -1
  146. package/src/components/xform/form-designer/setting-panel/property-editor/field-divider/contentPosition-editor.vue +1 -1
  147. package/src/components/xform/form-designer/setting-panel/property-editor/field-dropdown-menu/dropdown-menu-editor.vue +59 -59
  148. package/src/components/xform/form-designer/setting-panel/property-editor/field-echart/echart-bar-editor.vue +11 -11
  149. package/src/components/xform/form-designer/setting-panel/property-editor/field-echart/echart-category-editor.vue +10 -10
  150. package/src/components/xform/form-designer/setting-panel/property-editor/field-echart/echart-pie-editor.vue +12 -12
  151. package/src/components/xform/form-designer/setting-panel/property-editor/field-file-upload/file-upload-fileTypes-editor.vue +44 -44
  152. package/src/components/xform/form-designer/setting-panel/property-editor/field-html-text/htmlContent-editor.vue +29 -29
  153. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import-button-editor.vue +6 -6
  154. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +4 -4
  155. package/src/components/xform/form-designer/setting-panel/property-editor/field-number/controlsPosition-editor.vue +1 -1
  156. package/src/components/xform/form-designer/setting-panel/property-editor/field-picture-upload/picture-upload-fileTypes-editor.vue +44 -44
  157. package/src/components/xform/form-designer/setting-panel/property-editor/field-print-button/print-button-editor.vue +115 -115
  158. package/src/components/xform/form-designer/setting-panel/property-editor/field-print-button/print-detail-button-editor.vue +115 -115
  159. package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/highThreshold-editor.vue +1 -1
  160. package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/lowThreshold-editor.vue +1 -1
  161. package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/rate-defaultValue-editor.vue +1 -1
  162. package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/rate-max-editor.vue +1 -1
  163. package/src/components/xform/form-designer/setting-panel/property-editor/field-script/script-editor.vue +4 -4
  164. package/src/components/xform/form-designer/setting-panel/property-editor/field-script-input/script-input-editor.vue +4 -4
  165. package/src/components/xform/form-designer/setting-panel/property-editor/field-static-text/fontSize-editor.vue +1 -1
  166. package/src/components/xform/form-designer/setting-panel/property-editor/field-static-text/textContent-editor.vue +1 -1
  167. package/src/components/xform/form-designer/setting-panel/property-editor/field-status/field-status-editor.vue +3 -3
  168. package/src/components/xform/form-designer/setting-panel/property-editor/field-switch/activeText-editor.vue +1 -1
  169. package/src/components/xform/form-designer/setting-panel/property-editor/field-switch/inactiveText-editor.vue +1 -1
  170. package/src/components/xform/form-designer/setting-panel/property-editor/field-switch/switchWidth-editor.vue +1 -1
  171. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-button-editor.vue +2 -2
  172. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-item-button-editor.vue +74 -74
  173. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/table-export-button-editor.vue +3 -3
  174. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +34 -18
  175. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-format-editor.vue +1 -1
  176. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-timeLimit-editor.vue +53 -0
  177. package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-defaultValue-editor.vue +35 -18
  178. package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-format-editor.vue +1 -1
  179. package/src/components/xform/form-designer/setting-panel/property-editor/field-vabSearch/vabSearchField-editor.vue +2 -2
  180. package/src/components/xform/form-designer/setting-panel/property-editor/field-vabSearch/vabSearchName-editor.vue +2 -2
  181. package/src/components/xform/form-designer/setting-panel/property-editor/field-vabUpload/field-vabUpload-editor.vue +1 -1
  182. package/src/components/xform/form-designer/setting-panel/property-editor/field-vabUpload2/field-vabUpload2-editor.vue +1 -1
  183. package/src/components/xform/form-designer/setting-panel/property-editor/field-vue-page/vue-page-editor.vue +2 -2
  184. package/src/components/xform/form-designer/setting-panel/property-editor/fileMaxSize-editor.vue +1 -1
  185. package/src/components/xform/form-designer/setting-panel/property-editor/fileTypesSelect.vue +176 -176
  186. package/src/components/xform/form-designer/setting-panel/property-editor/fixedQuery-editor.vue +39 -0
  187. package/src/components/xform/form-designer/setting-panel/property-editor/formScriptEnabled-editor.vue +41 -6
  188. package/src/components/xform/form-designer/setting-panel/property-editor/formatType-editor.vue +2 -2
  189. package/src/components/xform/form-designer/setting-panel/property-editor/formula-editor.vue +972 -972
  190. package/src/components/xform/form-designer/setting-panel/property-editor/iconClass-editor.vue +1 -1
  191. package/src/components/xform/form-designer/setting-panel/property-editor/label-editor.vue +1 -1
  192. package/src/components/xform/form-designer/setting-panel/property-editor/labelAlign-editor.vue +1 -1
  193. package/src/components/xform/form-designer/setting-panel/property-editor/labelColor-editor.vue +1 -1
  194. package/src/components/xform/form-designer/setting-panel/property-editor/labelIconPosition-editor.vue +1 -1
  195. package/src/components/xform/form-designer/setting-panel/property-editor/labelWidth-editor.vue +1 -1
  196. package/src/components/xform/form-designer/setting-panel/property-editor/limit-editor.vue +1 -1
  197. package/src/components/xform/form-designer/setting-panel/property-editor/max-editor.vue +1 -1
  198. package/src/components/xform/form-designer/setting-panel/property-editor/maxLength-editor.vue +1 -1
  199. package/src/components/xform/form-designer/setting-panel/property-editor/min-editor.vue +1 -1
  200. package/src/components/xform/form-designer/setting-panel/property-editor/minLength-editor.vue +1 -1
  201. package/src/components/xform/form-designer/setting-panel/property-editor/multipleLimit-editor.vue +1 -1
  202. package/src/components/xform/form-designer/setting-panel/property-editor/name-editor.vue +15 -4
  203. package/src/components/xform/form-designer/setting-panel/property-editor/oplog-editor.vue +3 -3
  204. package/src/components/xform/form-designer/setting-panel/property-editor/placeholder-editor.vue +1 -1
  205. package/src/components/xform/form-designer/setting-panel/property-editor/precision-editor.vue +1 -1
  206. package/src/components/xform/form-designer/setting-panel/property-editor/prefixIcon-editor.vue +14 -15
  207. package/src/components/xform/form-designer/setting-panel/property-editor/project-tag-editor.vue +6 -6
  208. package/src/components/xform/form-designer/setting-panel/property-editor/relative-default-block.vue +369 -0
  209. package/src/components/xform/form-designer/setting-panel/property-editor/requiredHint-editor.vue +1 -1
  210. package/src/components/xform/form-designer/setting-panel/property-editor/rows-editor.vue +1 -1
  211. package/src/components/xform/form-designer/setting-panel/property-editor/space-editor-editor.vue +1 -1
  212. package/src/components/xform/form-designer/setting-panel/property-editor/startPlaceholder-editor.vue +1 -1
  213. package/src/components/xform/form-designer/setting-panel/property-editor/step-editor.vue +1 -1
  214. package/src/components/xform/form-designer/setting-panel/property-editor/styleTableClass-editor.vue +1 -1
  215. package/src/components/xform/form-designer/setting-panel/property-editor/styleTitClass-editor.vue +1 -1
  216. package/src/components/xform/form-designer/setting-panel/property-editor/suffixIcon-editor.vue +14 -15
  217. package/src/components/xform/form-designer/setting-panel/property-editor/tempStorage-editor.vue +1 -1
  218. package/src/components/xform/form-designer/setting-panel/property-editor/textFlag-editor.vue +2 -3
  219. package/src/components/xform/form-designer/setting-panel/property-editor/type-editor.vue +1 -1
  220. package/src/components/xform/form-designer/setting-panel/property-editor/uploadTip-editor.vue +1 -1
  221. package/src/components/xform/form-designer/setting-panel/property-editor/uploadURL-editor.vue +1 -1
  222. package/src/components/xform/form-designer/setting-panel/property-editor/urlValueEnabled-editor.vue +91 -0
  223. package/src/components/xform/form-designer/setting-panel/property-editor/validation-editor.vue +1 -1
  224. package/src/components/xform/form-designer/setting-panel/property-editor/validationHint-editor.vue +1 -1
  225. package/src/components/xform/form-designer/setting-panel/property-editor/widgetWidth-editor.vue +1 -1
  226. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +374 -351
  227. package/src/components/xform/form-designer/toolbar-panel/index.vue +266 -103
  228. package/src/components/xform/form-designer/toolbar-panel/indexMixin.js +655 -589
  229. package/src/components/xform/form-designer/widget-panel/index.vue +391 -341
  230. package/src/components/xform/form-designer/widget-panel/indexMixin.js +351 -308
  231. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +4642 -4028
  232. package/src/components/xform/form-render/container-item/containerItemMixin.js +76 -61
  233. package/src/components/xform/form-render/container-item/data-table-item.vue +24 -13
  234. package/src/components/xform/form-render/container-item/data-table-mixin.js +5927 -3400
  235. package/src/components/xform/form-render/container-item/detail-h5-item.vue +173 -173
  236. package/src/components/xform/form-render/container-item/detail-item.vue +446 -224
  237. package/src/components/xform/form-render/container-item/detail-plain-item.vue +92 -0
  238. package/src/components/xform/form-render/container-item/list-h5-item.vue +1186 -411
  239. package/src/components/xform/form-render/container-item/tab-item.vue +129 -125
  240. package/src/components/xform/form-render/container-item/table-item.vue +0 -3
  241. package/src/components/xform/form-render/container-item/table2-item.vue +18 -10
  242. package/src/components/xform/form-render/dynamicDialogRender.js +140 -99
  243. package/src/components/xform/form-render/index.vue +8 -8
  244. package/src/components/xform/form-render/indexMixin.js +5299 -3766
  245. package/src/components/xform/form-render/refMixin.js +14 -11
  246. package/src/components/xform/lang/en-US.js +473 -438
  247. package/src/components/xform/lang/en-US_extension.js +4 -0
  248. package/src/components/xform/lang/zh-CN.js +646 -620
  249. package/src/components/xform/mixins/defaultHandle.js +363 -26
  250. package/src/components/xform/mixins/scriptHttp.js +54 -51
  251. package/src/components/xform/utils/attachmentValueUtil.js +239 -0
  252. package/src/components/xform/utils/fixedQueryUtil.js +93 -0
  253. package/src/components/xform/utils/format.js +195 -169
  254. package/src/components/xform/utils/queryParamUtil.js +84 -0
  255. package/src/components/xform/utils/tableColumnHelper.js +7 -8
  256. package/src/components/xform/utils/util.js +1663 -1551
  257. package/src/components/xform/utils/validators.js +100 -48
  258. package/src/index.js +403 -89
  259. package/src/layout/components/AppMain.vue +147 -119
  260. package/src/layout/components/Sidebar/default.vue +109 -59
  261. package/src/layout/components/TagsView/index.vue +1 -1
  262. package/src/layout/components/extractedCode/queryDialog.vue +33 -26
  263. package/src/layout/components/extractedCode/viewDialog.vue +207 -193
  264. package/src/layout/components/langTool.vue +128 -123
  265. package/src/layout/defaultLayout.vue +170 -158
  266. package/src/mixins/wf/index.js +40 -38
  267. package/src/public-path.js +38 -0
  268. package/src/router/modules/system.js +4 -0
  269. package/src/store/config/index.js +945 -669
  270. package/src/utils/pdfUtil.js +428 -70
  271. package/src/views/bd/setting/bd_company_env/dialog.vue +1 -1
  272. package/src/views/bd/setting/formVersion/button.vue +5 -0
  273. package/src/views/bd/setting/formVersion/ftHistoryDialog.vue +21 -10
  274. package/src/views/bd/setting/formVersion/link.vue +5 -0
  275. package/src/views/bd/setting/form_script/edit.vue +1 -0
  276. package/src/views/bd/setting/form_script/edit1.vue +1 -0
  277. package/src/views/bd/setting/form_script/form_list.vue +1 -0
  278. package/src/views/bd/setting/form_script/list.vue +1 -0
  279. package/src/views/bd/setting/form_script/list1.vue +2 -0
  280. package/src/views/bd/setting/form_template/edit.vue +1 -0
  281. package/src/views/bd/setting/form_template/list.vue +2 -0
  282. package/src/views/bd/setting/form_template/mixins/edit.js +77 -74
  283. package/src/views/bd/setting/table_model/edit.vue +16 -29
  284. package/src/views/bd/setting/table_model/list.vue +1 -0
  285. package/src/views/bd/setting/table_model/mixins/edit.js +295 -149
  286. package/src/views/bd/setting/table_model/mixins/zdDialog.js +32 -0
  287. package/src/views/support/export_template/list.vue +1 -1
  288. package/src/views/user/company_info/edit.vue +149 -88
  289. package/src/views/user/form/form_template/dialog.vue +1 -1
  290. package/src/views/user/form/form_template/itemList.vue +1 -1
  291. package/src/views/user/form/form_template/list.vue +1 -1
  292. package/src/views/user/form/form_template_field/dialog.vue +1 -1
  293. package/src/views/user/form/form_type/dialog.vue +1 -1
  294. package/src/views/user/form/form_type/list.vue +1 -1
  295. package/src/views/user/form/report_requestaccess/dialog.vue +1 -1
  296. package/src/views/user/form/report_requestaccess/list.vue +1 -1
  297. package/src/views/user/form/vform/designer.vue +51 -22
  298. package/src/views/user/form/vform/render.vue +21 -23
  299. package/src/views/user/form/view/list.vue +134 -37
  300. package/src/views/user/wf/wfReport/index.vue +24 -1
  301. package/src/views/user/wf/wf_manage/list.vue +8 -4
  302. package/src/components/xform/form-designer/form-widget/dialog/formDrawer.vue +0 -209
  303. package/src/components/xform/form-designer/form-widget/dialog/importDialogMixin - /345/211/257/346/234/254.js" +0 -1639
  304. package/src/views/bd/setting/table_model/mixins/edit copy.js +0 -903
  305. package/src/views/user/menu/voc_list.vue +0 -686
@@ -1,1772 +1,1774 @@
1
- /**version-1.0*/
2
- import { read, utils } from "xlsx";
3
- import axios from "axios";
4
- import SparkMD5 from "spark-md5";
5
-
6
- let tmixins = {};
7
- let XLSX = window.XLSX || { read, utils };
8
- import { getToken } from "../../../../../utils/auth";
9
- import XEUtils from "xe-utils";
10
- import { getErrorMsg } from "@base/utils/index.js";
11
-
12
- let configUtil = {
13
- baseUrl: process.env.VUE_APP_BASE_API,
14
- XLSX,
15
- getToken,
16
- };
17
- let importTimer = null;
18
- let loadingObj = null;
19
- tmixins = {
20
- name: "excelImport",
21
- props: ["param", "parentTarget"],
22
- inject: ["getReportTemplate", "formHttp"],
23
- data() {
24
- return {
25
- excTime: 0,
26
- showImportDialog: false,
27
- showImportDialog2: false,
28
- falseValue: false,
29
- fileRaw: false,
30
- isEnd: false,
31
- currentIndex: 0,
32
- excelTemplate: "",
33
- prefix: "/user",
34
- dataSize: 0,
35
- totalSuccessNum: 0,
36
- totalErrorNum: 0,
37
- percentageNum: 0,
38
- successRows: [],
39
- failRows: [],
40
- oriCols: [],
41
- showImportResult: false,
42
- resultType: "",
43
- option: {},
44
- showContent: false,
45
- resOption: {},
46
- fileCellFields: [],
47
- importLoading: false,
48
- loadingTitle: null,
49
-
50
- percent1: 0,
51
- percent2: 0,
52
- percent3: 0,
53
-
54
- loadingPercent: 0,
55
- handleRowSize: 1,
56
-
57
- headerRows: 3,
58
- };
59
- },
60
- computed: {
61
- importFileLimitSize() {
62
- return Math.min(
63
- this.param?.importOption?.importFileLimitSize || 200,
64
- 200
65
- );
66
- },
67
- },
68
- created() {
69
- this.exc();
70
- },
71
- beforeDestroy() {
72
- this.clearImportTimer();
73
- },
74
- methods: {
75
- initResGird() {
76
- let that = this;
77
- let tableRef = "resGrid";
78
- let columns = [
79
- {
80
- type: "checkbox",
81
- fixed: "left",
82
- width: 48,
83
- resizable: false,
84
- headerClassName: "vxe-hcs",
85
- className: "vxe-hcs",
86
- },
87
- {
88
- field: "impNumber",
89
- title: this.$t2("行号", "components.excelImport.impNumber"),
90
- width: 100,
91
- fixed: "left",
92
- },
93
- {
94
- field: "_resultContent",
95
- title: this.$t2("结果", "components.excelImport.resultContent"),
96
- width: 250,
97
- fixed: "left",
98
- slots: {
99
- default: ({ row, $rowIndex, $table }) => {
100
- return that.handleRes(row._resultContent);
101
- },
102
- },
103
- },
104
- ];
105
- let cCols = this.oriCols.map((oriCol, index) => {
106
- let col = {
107
- field: oriCol.field,
108
- title: oriCol.title,
109
- width: 150,
110
- ...oriCol.otherConfig,
111
- };
112
- if (index === 0) {
113
- col.fixed = "left";
114
- }
115
- return col;
116
- });
117
- columns = columns.concat(cCols);
118
-
119
- let tableOption = {
120
- vue: this,
121
- tableRef: tableRef,
122
- tableNameRequired: false,
123
- columns: columns,
124
- config: {
125
- toolbarConfig: {
126
- custom: false,
127
- },
128
- },
129
- };
130
-
131
- this.$vxeTableUtil.initVxeTable(tableOption).then((opts) => {
132
- this.resOption = opts;
133
- });
134
- },
135
- exc() {
136
- this.option = this.param;
137
- this.showContent = true;
138
- this.showImportDialog = true;
139
- this.showImportDialog2 = false;
140
- },
141
- showSuccessResult() {
142
- this.showImportResult = true;
143
- this.resultType = 1;
144
- this.$nextTick(() => {
145
- this.initResGird();
146
- this.$nextTick(() => {
147
- let tDatas = this.successRows.map((item, index) => {
148
- item.id = index;
149
- return item;
150
- });
151
- this.$refs.resGrid.loadData(tDatas);
152
- });
153
- });
154
- },
155
- showErrorResult() {
156
- this.showImportResult = true;
157
- this.resultType = 0;
158
- this.$nextTick(() => {
159
- this.initResGird();
160
- this.$nextTick(() => {
161
- let tDatas = this.failRows.map((item, index) => {
162
- item.id = index;
163
- return item;
164
- });
165
- this.$refs.resGrid.loadData(tDatas);
166
- });
167
- });
168
- },
169
- fileChange(file) {
170
- if (file) {
171
- this.fileRaw = file.raw;
172
- } else {
173
- this.fileRaw = false;
174
- }
175
- },
176
- dialogClose1() {
177
- this.importLoading = false;
178
- if (!this.showImportDialog2) {
179
- this.$emit("update:visiable", false);
180
- this.showContent = false;
181
- }
182
- },
183
- async dialogPrimary1() {
184
- let that = this;
185
- let option = this.option;
186
-
187
- let fileRaw = this.fileRaw;
188
- if (!fileRaw) {
189
- this.$baseAlert(
190
- this.$t2("请上传附件", "components.excelImport.warmMsg1")
191
- );
192
- return false;
193
- }
194
- let importFileLimitSize = this.importFileLimitSize;
195
- let fileSize = fileRaw.size;
196
- let limitSize = importFileLimitSize * 1024 * 1024;
197
- if (fileSize > limitSize) {
198
- this.$baseAlert(
199
- this.$t1("导入文件不允许超过{fileSize}MB", {
200
- fileSize: importFileLimitSize,
201
- })
202
- );
203
- return false;
204
- }
205
-
206
- if (option.importFrontOnly) {
207
- this.dialogPrimary3();
208
- return false;
209
- }
210
-
211
- /* this.createImportTimer();
212
- this.showImportDialog = false;
213
- if (!option.onConfirm) {
214
- this.showImportDialog2 = true;
215
- } */
216
- // this.$nextTick(() => {
217
- try {
218
- this.readExcel(this.fileRaw, function (resultData) {
219
- that.createImportTimer();
220
- that.showImportDialog = false;
221
- if (!option.onConfirm) {
222
- that.showImportDialog2 = true;
223
- }
224
- that.$nextTick(() => {
225
- if (option.onConfirm) {
226
- option.onConfirm(resultData.data, that.fileRaw);
227
- } else {
228
- that.handleBeforeImport0(that.fileRaw, resultData, () => {
229
- that.syncDataForImport({
230
- multi: false,
231
- data: resultData,
232
- // saveUrl: saveUrl
233
- });
234
- });
235
- }
236
- });
237
- });
238
- } catch (et) {
239
- that.clearImportTimer();
240
- console.error(et);
241
- }
242
- // });
243
- },
244
- handleBeforeImport(file, resultData, callback) {
245
- let importOption = this.option.importOption;
246
- let that = this;
247
- if (importOption.onBeforeImport) {
248
- const toDo = (res) => {
249
- let rows = res?.objx || [];
250
- rows.forEach((row, rowIndex) => {
251
- let item = resultData[rowIndex];
252
- Object.keys(row).forEach((key) => {
253
- item[key] = row[key];
254
- });
255
- });
256
- callback && callback();
257
- };
258
- this.getFieldTarget().handleCustomEvent(
259
- importOption.onBeforeImport,
260
- ["file", "resultData", "done"],
261
- [file, resultData, toDo]
262
- );
263
- } else {
264
- callback && callback();
265
- }
266
- },
267
- handleBeforeImport0(file, resultData, callback) {
268
- if (!this.showImportDialog2) return;
269
- let importOption = this.option.importOption;
270
- if (!importOption.enabledImportPreHandle) {
271
- this.handleBeforeImport(file, resultData, () => {
272
- callback && callback();
273
- });
274
- return;
275
- }
276
-
277
- this.uploadFile(() => {
278
- this.importLoading = false;
279
- this.handleBeforeImport(file, resultData, () => {
280
- callback && callback();
281
- });
282
- });
283
- return;
284
- },
285
- handleBeforeClose(hide) {
286
- this.option.onCancel &&
287
- this.option.onCancel(this.getCallbackData(), this.fileRaw);
288
- let importOption = this.option.importOption;
289
- this.getFieldTarget().handleCustomEvent(
290
- importOption.onSuccessImport,
291
- ["resultData", "file"],
292
- [this.getCallbackData(), this.fileRaw]
293
- );
294
- this.handleTableCallback();
295
- hide();
296
- },
297
- dialogClose2() {
298
- this.showImportDialog2 = false;
299
- this.option.onBeforeCancel &&
300
- this.option.onBeforeCancel(this.getCallbackData(), this.fileRaw);
301
- let importOption = this.option.importOption;
302
- this.getFieldTarget().handleCustomEvent(
303
- importOption.onSuccessImport,
304
- ["resultData", "file"],
305
- [this.getCallbackData(), this.fileRaw]
306
- );
307
- this.handleTableCallback();
308
- },
309
- handleClose2() {
310
- this.clearImportTimer();
311
- this.showImportDialog2 = false;
312
- this.showContent = false;
313
- this.option.onClose &&
314
- this.option.onClose(this.getCallbackData(), this.fileRaw);
315
- this.option.callback &&
316
- this.option.callback(this.getCallbackData(), this.fileRaw);
317
- this.dialogClose1();
318
- },
319
- dialogPrimary2() {
320
- let importOption = this.option.importOption;
321
- this.showImportDialog2 = false;
322
- this.option.onBeforeConfirm &&
323
- this.option.onBeforeConfirm(this.getCallbackData(), this.fileRaw);
324
- this.getFieldTarget().handleCustomEvent(
325
- importOption.onSuccessImport,
326
- ["resultData", "file"],
327
- [this.getCallbackData(), this.fileRaw]
328
- );
329
- this.handleTableCallback();
330
- },
331
- getCallbackData() {
332
- return {
333
- ...this.resultData,
334
- successRows: this.successRows,
335
- failRows: this.failRows,
336
- };
337
- },
338
-
339
- /*dialogClose2(flag) {
340
- let importOption = this.option.importOption;
341
- this.clearImportTimer();
342
- this.showImportDialog2 = false;
343
- this.dialogClose1();
344
- this.handleTableCallback(flag);
345
- this.parentTarget.handleCustomEvent(importOption.onSuccessImport, ['resultData', 'file'], [this.resultData, this.fileRaw])
346
- this.option.callback && this.option.callback(this.resultData, this.fileRaw);
347
- },
348
- dialogPrimary2() {
349
- let importOption = this.option.importOption;
350
- this.clearImportTimer();
351
- this.showImportDialog2 = false;
352
- this.dialogClose1()
353
- this.handleTableCallback();
354
- let fileRaw = this.fileRaw;
355
- this.parentTarget.handleCustomEvent(importOption.onSuccessImport, ['resultData', 'file'], [this.resultData, this.fileRaw])
356
- this.option.callback && this.option.callback(this.resultData, this.fileRaw);
357
- },*/
358
- handleTableCallback(flag) {
359
- if (flag === 0) return;
360
- let importOption = this.option.importOption;
361
- let tableTarget;
362
- if (importOption.tableRef)
363
- tableTarget = this.getFieldTarget().getWidgetRef(importOption.tableRef);
364
- if (tableTarget) {
365
- let isQueryTable = tableTarget.widget.options.isQueryTable;
366
- if (isQueryTable) {
367
- tableTarget.searchEvent();
368
- }
369
- }
370
- },
371
- async readExcel(file, callback) {
372
- let that = this;
373
- let option = this.option;
374
-
375
- if (option.importOption.multipleSheet) {
376
- this.readExcel2(file, callback);
377
- return;
378
- }
379
-
380
- const fileReader = new FileReader();
381
- fileReader.onload = async (ev) => {
382
- let resultData;
383
- try {
384
- const data = ev.target.result;
385
- const workbook = configUtil.XLSX.read(data, {
386
- type: "binary",
387
- });
388
-
389
- let sheet = workbook.Sheets[workbook.SheetNames[0]];
390
- if (sheet["!ref"] === undefined || sheet["!ref"] === null) {
391
- /*that.showImportDialog2 = false;
392
- that.showContent = false;
393
- that.clearImportTimer();*/
394
- that.$baseAlert(
395
- this.$t2(
396
- "请使用正确的导入模版!",
397
- "components.excelImport.warmMsg2"
398
- )
399
- );
400
- that.handleClose2();
401
- return false;
402
- }
403
- let range = configUtil.XLSX.utils.decode_range(sheet["!ref"]);
404
- let dataSize = range.e.r + 1; //行数
405
- that.dataSize = dataSize - 3 >= 0 ? dataSize - 3 : 0;
406
- let titles = [];
407
- let fields = [];
408
-
409
- const ws = workbook.Sheets[sheet];
410
-
411
- let prefix = option.prefix;
412
- let excelUrl = option.excel;
413
-
414
- let excelRows = [];
415
- let row;
416
- let rowNum;
417
- let colNum;
418
- for (rowNum = range.s.r; rowNum <= range.e.r; rowNum++) {
419
- row = [];
420
- for (colNum = range.s.c; colNum <= range.e.c; colNum++) {
421
- let nextCell =
422
- sheet[
423
- configUtil.XLSX.utils.encode_cell({
424
- r: rowNum,
425
- c: colNum,
426
- })
427
- ];
428
- if (typeof nextCell === "undefined") {
429
- row.push(void 0);
430
- } else {
431
- row.push(nextCell.w.trim());
432
- }
433
- }
434
- if (rowNum === 1) {
435
- titles = row;
436
- }
437
- if (rowNum === 2) {
438
- fields = row;
439
- let checkResult = true;
440
- /*await that.checkExcelForImport(titles, fields, excelUrl, prefix).then(
441
- res => {
442
- if (res.type !== "success") {
443
- checkResult = false;
444
- }
445
- });
446
- if (!checkResult) {
447
- that.showContent = false;
448
- that.clearImportTimer();
449
- return false;
450
- }*/
451
- }
452
- if (rowNum > 2) {
453
- let item = {};
454
- for (let i = 0; i < fields.length; i++) {
455
- let field = fields[i];
456
- if (field) {
457
- item[field] = row[i] ?? null;
458
- }
459
- }
460
- excelRows.push(item);
461
- }
462
- }
463
- if (
464
- !titles.length ||
465
- !fields.length ||
466
- titles.length !== fields.length
467
- ) {
468
- // that.showContent = false;
469
- // that.clearImportTimer();
470
- that.$baseAlert(
471
- this.$t2(
472
- "请使用正确的导入模版!",
473
- "components.excelImport.warmMsg2"
474
- )
475
- );
476
- that.handleClose2();
477
- return false;
478
- }
479
-
480
- let columns = [];
481
- let cols = [];
482
- let uniqueFields = [];
483
- for (let i = 0; i < titles.length; i++) {
484
- let title = titles[i];
485
- if (title) {
486
- let field = fields[i];
487
- if (field === null || field === undefined) {
488
- // that.showContent = false;
489
- // that.clearImportTimer();
490
- that.$baseAlert(
491
- this.$t2(
492
- "请使用正确的导入模版!",
493
- "components.excelImport.warmMsg2"
494
- )
495
- );
496
- that.handleClose2();
497
- return false;
498
- }
499
- let t = title.substr(-1);
500
- let u = title.length >= 2 ? title.substr(-2) : title;
501
- let isNeed = false;
502
- if (t === "*") {
503
- isNeed = true;
504
- }
505
- let isUnique = false;
506
- if (u === "**") {
507
- uniqueFields.push(field);
508
- isUnique = true;
509
- }
510
-
511
- let otherConfig = {};
512
- let isFile = false;
513
- if (field.startsWith("attachments_")) {
514
- that.fileCellFields.push(field);
515
- isFile = true;
516
- otherConfig = {
517
- slots: {
518
- default: "attachment",
519
- },
520
- };
521
- }
522
-
523
- let col = {
524
- field: field,
525
- title: title,
526
- width: 100,
527
- isNeed: isNeed,
528
- isUnique: isUnique,
529
- isFile,
530
- otherConfig,
531
- };
532
- cols.push(col);
533
- }
534
- }
535
-
536
- let oriCols = JSON.parse(JSON.stringify(cols)); //列信息
537
- if (uniqueFields.length) {
538
- //分组唯一字段为空时,全部不发包。
539
- for (let i = 0; i < oriCols.length; i++) {
540
- let oriCol = oriCols[i];
541
- if (oriCol.isNeed) {
542
- for (let j = 0; j < excelRows.length; j++) {
543
- let data = excelRows[j];
544
- let value = data[oriCol.field];
545
- if (value === null || value === undefined || value === "") {
546
- that.clearImportTimer();
547
- that.$baseAlert(
548
- this.$t2(
549
- "第" + (j + 4) + "行[" + oriCol.title + "]不能为空;",
550
- "components.excelImport.warmMsg3",
551
- {
552
- lineNo: j + 4,
553
- title: oriCol.title,
554
- }
555
- )
556
- );
557
- that.handleClose2();
558
- return false;
559
- }
560
- }
561
- }
562
- }
563
- }
564
-
565
- this.oriCols = oriCols;
566
-
567
- resultData = {
568
- data: excelRows,
569
- titles: titles,
570
- fields: fields,
571
- uniqueFields: uniqueFields,
572
- oriCols: oriCols,
573
- };
574
- this.resultData = resultData;
575
- callback(resultData);
576
- } catch (et) {
577
- that.showContent = false;
578
- that.clearImportTimer();
579
- console.error(et);
580
- }
581
- };
582
- fileReader.readAsBinaryString(file);
583
- },
584
- async checkExcelForImport(titles, fields, turl, prefix) {
585
- if (!this.showImportDialog2) return;
586
- let that = this;
587
- let data = {
588
- filed_name: fields,
589
- field_note: titles,
590
- url: turl,
591
- };
592
- let param = JSON.stringify(data);
593
- return this.$http({
594
- url: prefix + "/sf_common/compareExcelFields",
595
- method: "post",
596
- headers: {
597
- "Content-Type": "application/json;charset=utf-8",
598
- },
599
- // data: param,
600
- data: data,
601
- });
602
- },
603
- saveImportHandle(data, opt) {
604
- let multi = this.option.multi;
605
- let importOption = this.option.importOption;
606
-
607
- let entity = importOption.importEntity;
608
-
609
- if (!entity) return;
610
-
611
- let reportTemplate = this.getReportTemplate();
612
- let formCode = reportTemplate?.formCode;
613
- let scriptCode = importOption.importScriptCode || "import";
614
- // let config = option?.config;
615
-
616
- // let reqData = this.getReqFormData();
617
- let fileCellFields = this.fileCellFields;
618
- let formData = null;
619
- if (multi) {
620
- formData = data;
621
- } else {
622
- formData = {
623
- [entity]: { ...data },
624
- };
625
- if (fileCellFields.length) {
626
- fileCellFields.forEach((field) => {
627
- let attachments = data[field] || [];
628
- delete formData[entity][field];
629
- formData[field] = attachments;
630
- });
631
- }
632
- }
633
-
634
- let reqData = {
635
- formCode: formCode,
636
- formVersion: reportTemplate.formVersion,
637
- taBm: entity,
638
- data: formData,
639
- };
640
-
641
- this.formHttp({
642
- scriptCode: scriptCode,
643
- data: reqData,
644
- modal: false,
645
- ...opt,
646
- });
647
- },
648
- syncDataForImport(opts) {
649
- let that = this;
650
- let multi = this.option.multi;
651
- let resultData = this.resultData;
652
- let datas = resultData.data;
653
- let titles = resultData.titles;
654
- let fields = resultData.fields;
655
- let uniqueFields = resultData.uniqueFields;
656
- let saveUrl = opts.saveUrl;
657
- let size = datas.length;
658
- let index = 0;
659
- let successNum = 0;
660
- let failNum = 0;
661
- let dialogObj = this.$refs.importDialog.$el;
662
- let successNumObj = dialogObj.querySelector(".successNum");
663
- let failNumObj = dialogObj.querySelector(".failNum");
664
- let percentageObj = dialogObj.querySelector(".percentage");
665
- let doneNumObj = dialogObj.querySelector(".doneNum");
666
- dialogObj.querySelector(".dataSize").innerText = size;
667
-
668
- that.successRows = [];
669
- that.failRows = [];
670
-
671
- let multiSize = this.option.multiSize || 2;
672
-
673
- let groupIndex = 0;
674
- let groupDatas = [];
675
- if (uniqueFields.length) {
676
- let d = XEUtils.groupBy(datas, function (item, itemIndex, items) {
677
- let keyArr = [];
678
- uniqueFields.forEach((field) => {
679
- keyArr.push(item[field]);
680
- });
681
- return keyArr.join("&_&");
682
- });
683
- for (let key in d) {
684
- groupDatas.push(d[key]);
685
- }
686
- datas.forEach((item, itemIndex) => {
687
- item.impSeq = itemIndex;
688
- item.impNumber = itemIndex + 4;
689
- });
690
- }
691
-
692
- let compareV = function (property) {
693
- return function (a, b) {
694
- let value1 = a[property];
695
- let value2 = b[property];
696
- return value1 - value2;
697
- };
698
- };
699
-
700
- let prevHandleData = function (percentageStr, excNum) {
701
- successNumObj.innerText = successNum;
702
- failNumObj.innerText = failNum;
703
- doneNumObj.innerText = successNum + failNum;
704
- that.percentageNum = percentageStr;
705
- let isEnd = false;
706
- if (multi && uniqueFields.length) {
707
- isEnd = groupIndex + 1 >= groupDatas.length;
708
- } else {
709
- isEnd = index + excNum >= size;
710
- }
711
- if (!isEnd) {
712
- index = index + excNum;
713
- groupIndex = groupIndex + 1;
714
- setTimeout(function () {
715
- handleData();
716
- }, 1);
717
- } else {
718
- setTimeout(function () {
719
- that.clearImportTimer();
720
- }, 300);
721
- }
722
- };
723
-
724
- let getDefaultValue = (row) => {
725
- let value = null;
726
- let defaultValue = this.option.defaultValue;
727
- if (defaultValue) {
728
- if (typeof defaultValue === "function") {
729
- value = defaultValue(row) || {};
730
- } else {
731
- value = defaultValue || {};
732
- }
733
- }
734
- return value;
735
- };
736
-
737
- let handleData = () => {
738
- if (!that.isEnd && index < size) {
739
- let param;
740
- let excNum;
741
- if (multi) {
742
- if (!uniqueFields.length) {
743
- if (index + multiSize < size) {
744
- excNum = multiSize;
745
- } else {
746
- excNum = size - index;
747
- }
748
-
749
- let dataList = [];
750
- for (let i = 0; i < excNum; i++) {
751
- let mIndex = index + i;
752
- let mData = datas[mIndex];
753
- mData.impSeq = mIndex;
754
- mData.impNumber = mIndex + 4;
755
-
756
- let errorInfo = that.vailData(mData, opts);
757
- if (errorInfo.length > 0) {
758
- mData._resultType = "error";
759
- mData._resultContent = errorInfo;
760
- failNum++;
761
- that.failRows.push(mData);
762
- } else {
763
- let defaultValue = getDefaultValue(mData);
764
- if (defaultValue) {
765
- Object.assign(mData, defaultValue);
766
- }
767
- dataList.push(mData);
768
- }
769
-
770
- datas[mIndex] = mData;
771
- }
772
- if (dataList.length > 0) {
773
- param = dataList;
774
- }
775
- } else {
776
- excNum = groupDatas[groupIndex].length;
777
- param = groupDatas[groupIndex];
778
- }
779
- } else {
780
- let data = that.resultData.data[index];
781
- data.impSeq = index;
782
- data.impNumber = index + 4;
783
- excNum = 1;
784
- datas[index] = data;
785
-
786
- let errorInfo = that.vailData(data, opts);
787
- if (errorInfo.length > 0) {
788
- data._resultType = "error";
789
- data._resultContent = errorInfo;
790
- failNum++;
791
- that.failRows.push(data);
792
- } else {
793
- param = data;
794
- let defaultValue = getDefaultValue(data);
795
- if (defaultValue) {
796
- Object.assign(param, defaultValue);
797
- }
798
- }
799
- }
800
-
801
- let percentageStr = parseInt(((index + excNum) * 100) / size);
802
- if (param === null || param === undefined || param.length === 0) {
803
- if (that.showContent) {
804
- prevHandleData(percentageStr, excNum);
805
- }
806
- return;
807
- }
808
-
809
- that.saveImportHandle(param, {
810
- failMsg: false,
811
- callback: (resultMsg) => {
812
- if (multi) {
813
- if (resultMsg.type === "success") {
814
- let multiRows = resultMsg.objx;
815
- for (let i = 0; i < multiRows.length; i++) {
816
- let multiRow = multiRows[i];
817
- let data = datas[multiRow.impSeq];
818
- data._resultType = multiRow.impReturnType;
819
- data._resultContent =
820
- multiRow.impReturnType === "success"
821
- ? this.$t2(
822
- "导入成功",
823
- "components.excelImport.importSucess"
824
- )
825
- : multiRow.impReturnMsg;
826
- if (multiRow.impReturnType === "success") {
827
- successNum++;
828
- that.successRows.push(data);
829
- } else {
830
- failNum++;
831
- that.failRows.push(data);
832
- }
833
- }
834
-
835
- that.failRows = that.failRows.sort(compareV("impSeq"));
836
- } else {
837
- // error_win(resultMsg);
838
- // layer.close(opts.dialogObjIndex);
839
-
840
- let items = param.map((item) => {
841
- return {
842
- ...item,
843
- _resultType: "error",
844
- _resultContent: resultMsg.content,
845
- };
846
- });
847
- failNum = failNum + items.length;
848
- that.failRows.push(...items);
849
-
850
- that.failRows = that.failRows.sort(compareV("impSeq"));
851
-
852
- /* that.$errorMsg(resultMsg);
853
- that.showContent = false;
854
- that.clearImportTimer();
855
- return; */
856
- }
857
- } else {
858
- let data = that.resultData.data[index];
859
- data._resultType = resultMsg.type;
860
- data._resultContent =
861
- resultMsg.type === "success"
862
- ? this.$t2(
863
- "导入成功",
864
- "components.excelImport.importSucess"
865
- )
866
- : resultMsg.content;
867
-
868
- if (resultMsg.type === "success") {
869
- successNum++;
870
- that.successRows.push(data);
871
- } else {
872
- failNum++;
873
- that.failRows.push(data);
874
- }
875
- }
876
- if (that.showContent) {
877
- prevHandleData(percentageStr, excNum);
878
- }
879
- },
880
- error: (et) => {
881
- that.isEnd = true;
882
- that.clearImportTimer();
883
- console.error(et);
884
- },
885
- });
886
- }
887
- };
888
- handleData();
889
- },
890
- commonLocalDownload() {
891
- let importOption = this.option.importOption;
892
- let importAttachCode = importOption.importAttachCode;
893
- if (!importAttachCode) return;
894
- this.$http({
895
- url: USER_PREFIX + "/bd_attach_setting/getByCode",
896
- method: "post",
897
- data: {
898
- stringOne: importAttachCode,
899
- },
900
- success: (res) => {
901
- let fileObj = res.objx;
902
- let url = fileObj?.url;
903
- if (fileObj && url) {
904
- this.$commonFileUtil.downloadFile(url,fileObj.name);
905
- }
906
- },
907
- });
908
- },
909
- vailData(data, opts) {
910
- let oriCols = opts.data.oriCols;
911
- let errorInfo = [];
912
- for (let i = 0; i < oriCols.length; i++) {
913
- let oriCol = oriCols[i];
914
- if (oriCol.isNeed) {
915
- let value = data[oriCol.field];
916
- if (value === null || value === undefined || value === "") {
917
- errorInfo.push(
918
- this.$t2(
919
- "[" + oriCol.title + "]不能为空;",
920
- "components.excelImport.warmMsg4",
921
- { title: oriCol.title }
922
- )
923
- );
924
- }
925
- }
926
- }
927
- return errorInfo.join("");
928
- },
929
- handleRes(val) {
930
- /* let content = val;
931
- let text = content;
932
- if (content && content.indexOf("Exception") >= 0) {
933
- let index0 = content.lastIndexOf("*]");
934
- if (index0 >= 0) {
935
- text = content.substr(index0);
936
- if (text) {
937
- let index1 = text.indexOf("Exception:");
938
- if (index1 >= 0) {
939
- text = text.substr(index1 + 10);
940
- }
941
- }
942
- }
943
- } */
944
- let text = getErrorMsg(val);
945
- return text;
946
- },
947
- exportToExcel() {
948
- let str =
949
- this.resultType === 1
950
- ? this.$t2("成功", "components.excelImport.success")
951
- : this.$t2("失败", "components.excelImport.fail");
952
- let fileName =
953
- this.$t2("导入结果导出", "components.excelImport.exportFileName") +
954
- "(" +
955
- str +
956
- ")";
957
- let $grid = this.$refs.resGrid;
958
- let columns = $grid.getColumns();
959
- if (columns && columns.length) {
960
- let fields = columns
961
- .filter((item, index) => {
962
- return index > 0 && item.property;
963
- })
964
- .map((item, index) => {
965
- return item.property;
966
- });
967
- this.$refs.resGrid.exportData({
968
- filename: fileName,
969
- mode: "all",
970
- type: "csv",
971
- columns: fields,
972
- });
973
- }
974
- },
975
- createImportTimer() {
976
- this.excTime = 0;
977
- let beginTime = new Date().getTime();
978
- importTimer = setInterval(() => {
979
- let nowTime = new Date().getTime();
980
- let diffTime = (nowTime - beginTime) / 1000;
981
- this.$set(this, "excTime", this.$baseLodash.round(diffTime, 2));
982
- }, 100);
983
- },
984
- clearImportTimer() {
985
- clearInterval(importTimer);
986
- loadingObj && loadingObj.close();
987
- },
988
- getWidgetTarget() {},
989
- getFieldTarget() {
990
- return this.param.target;
991
- },
992
- async dialogPrimary3() {
993
- if (!this.fileRaw) {
994
- this.$baseAlert(
995
- this.$t2("请上传附件", "components.excelImport.warmMsg1")
996
- );
997
- return false;
998
- }
999
- let that = this;
1000
- let option = this.option;
1001
- loadingObj = this.$baseLoading({
1002
- target: document.body,
1003
- background: "unset",
1004
- });
1005
-
1006
- let importOption = option.importOption;
1007
- this.readExcel(this.fileRaw, function (resultData) {
1008
- let file = that.fileRaw;
1009
- let flag = false;
1010
- let done = () => {
1011
- if (flag) return;
1012
- flag = true;
1013
- that.showImportDialog = false;
1014
- return that
1015
- .getFieldTarget()
1016
- .handleCustomEvent(
1017
- importOption.onSuccessImport,
1018
- ["resultData", "file"],
1019
- [resultData, file]
1020
- );
1021
- };
1022
- const close = () => {
1023
- that.dialogClose1();
1024
- }
1025
- try {
1026
- if (importOption.onConfirmImportEnabled) {
1027
- if (
1028
- that
1029
- .getFieldTarget()
1030
- .handleCustomEvent(
1031
- importOption.onConfirmImport,
1032
- ["resultData", "file", "done", 'close'],
1033
- [resultData, file, done, close]
1034
- ) !== false
1035
- ) {
1036
- done();
1037
- }
1038
- } else if (importOption.tableRef) {
1039
- let tableRef = that
1040
- .getFieldTarget()
1041
- .getWidgetRef(importOption.tableRef);
1042
- tableRef && tableRef.addTableData(resultData.data);
1043
- done();
1044
- }
1045
- } catch (et) {
1046
- console.error(et);
1047
- }
1048
- setTimeout(function () {
1049
- loadingObj && loadingObj.close();
1050
- }, 200);
1051
- });
1052
- },
1053
-
1054
- //begin
1055
- fileParse(file, type = "base64", callback) {
1056
- let fileRead = new FileReader();
1057
- if (type === "base64") {
1058
- fileRead.readAsDataURL(file);
1059
- } else if (type === "buffer") {
1060
- fileRead.readAsArrayBuffer(file);
1061
- }
1062
- fileRead.onload = (ev) => {
1063
- callback(ev.target.result);
1064
- };
1065
- },
1066
- getUploadText(percent) {
1067
- return this.$t1("上传导入文件 {percent}%", { percent });
1068
- },
1069
- changeUploadPercent(percent) {
1070
- // return this.$t1('上传导入文件 {percent}%', {percent})
1071
- this.percent1 = percent;
1072
- this.loadingIndex = 1;
1073
- },
1074
- uploadFile(callback) {
1075
- let that = this;
1076
- that.loadingPercent = 0;
1077
- // that.loadingTitle = this.getUploadText(0);
1078
- that.changeUploadPercent(0);
1079
- let file = this.fileRaw;
1080
- let uploadChunkSize = 5;
1081
- this.importLoading = true;
1082
- this.fileUploadCallback = callback;
1083
- this.fileParse(file, "buffer", (buffer) => {
1084
- let spark = new SparkMD5.ArrayBuffer(),
1085
- chunkSize = uploadChunkSize * 1024 * 1024, // Read in chunks of 2MB
1086
- chunks = Math.ceil(file.size / chunkSize),
1087
- hash,
1088
- suffix;
1089
- spark.append(buffer);
1090
- hash = spark.end();
1091
- let md5 = hash;
1092
- let nameSplit = /\.([0-9a-zA-Z]+)$/i.exec(file.name);
1093
-
1094
- suffix = nameSplit && nameSplit.length > 1 ? nameSplit[1] : "";
1095
-
1096
- let chunkParam = {
1097
- fullFile: file,
1098
- chunkSize: chunkSize,
1099
- chunks: chunks,
1100
- chunkIndex: 0,
1101
- md5: hash,
1102
- uuid: "",
1103
- name: file.name,
1104
- };
1105
- file.chunkParam = chunkParam;
1106
-
1107
- this.sendRequest(file);
1108
- });
1109
- },
1110
- async sendRequest(fullFile) {
1111
- if (!this.showImportDialog2) return;
1112
- let that = this;
1113
- let uploadUrl = USER_PREFIX + "/excel_import/uploadFile";
1114
- let chunkParam = fullFile.chunkParam;
1115
- let target = that.$refs.upload;
1116
- let abort;
1117
- let config = {
1118
- headers: {
1119
- "Content-Type": "multipart/form-data",
1120
- },
1121
- cancelToken: new axios.CancelToken(function executor(c) {
1122
- abort = c;
1123
- fullFile.abort = c;
1124
- }),
1125
- onUploadProgress: (progressEvent) => {
1126
- let start = chunkParam.start;
1127
- let uploadedSize =
1128
- start +
1129
- Math.floor(
1130
- (chunkParam.currentSize * progressEvent.loaded) /
1131
- progressEvent.total
1132
- );
1133
- let percent = Math.floor((uploadedSize * 100) / fullFile.size);
1134
- if (percent === 100) {
1135
- percent = 99;
1136
- }
1137
- that.loadingPercent = percent;
1138
-
1139
- // that.$set(that, 'loadingTitle', this.getUploadText(percent))
1140
- that.changeUploadPercent(percent);
1141
- },
1142
- // failMsg: false,
1143
- modal: false,
1144
- callback: (res1) => {
1145
- if (res1.type === "success") {
1146
- let uuid = res1.objx.uuid;
1147
- chunkParam.uuid = uuid;
1148
- if (preFormData.chunk + 1 >= preFormData.chunks) {
1149
- let mergeData = {
1150
- name: chunkParam.name,
1151
- md5: chunkParam.md5,
1152
- uuid: uuid,
1153
- };
1154
- let _param = {
1155
- mergeData: mergeData,
1156
- chunkParam: chunkParam,
1157
- };
1158
- setTimeout(() => {
1159
- this.mergeFile(_param);
1160
- }, 100);
1161
- } else {
1162
- chunkParam.chunkIndex = chunkParam.chunkIndex + 1;
1163
- chunkParam.uuid = uuid;
1164
- setTimeout(() => {
1165
- this.sendRequest(fullFile);
1166
- }, 100);
1167
- }
1168
- } else {
1169
- this.dialogClose2(0);
1170
- }
1171
- return res1;
1172
- },
1173
- error: (err) => {
1174
- console.log(err);
1175
- this.dialogClose2(0);
1176
- },
1177
- }; //添加请求头
1178
-
1179
- let chunkIndex = chunkParam.chunkIndex;
1180
- let chunkSize = chunkParam.chunkSize;
1181
- let start = chunkIndex * chunkSize,
1182
- end =
1183
- start + chunkSize >= fullFile.size
1184
- ? fullFile.size
1185
- : start + chunkParam.chunkSize;
1186
- chunkParam.currentSize = end - start;
1187
- chunkParam.start = start;
1188
- chunkParam.end = end;
1189
-
1190
- let preFormData = {
1191
- file: fullFile.slice(start, end),
1192
- name: fullFile.name,
1193
- chunks: chunkParam.chunks,
1194
- chunk: chunkIndex,
1195
- md5: chunkParam.md5,
1196
- uuid: chunkParam.uuid,
1197
- };
1198
-
1199
- let formData = new FormData();
1200
- Object.keys(preFormData).forEach((key) => {
1201
- formData.append(key, preFormData[key]);
1202
- });
1203
-
1204
- let req = this.$http.post(uploadUrl, formData, config);
1205
- req.abort = () => {
1206
- abort(this.$t2("取消上传", "components.VabUpload.cancelUpload"));
1207
- };
1208
- },
1209
- mergeFile(param) {
1210
- if (!this.showImportDialog2) return;
1211
- let that = this;
1212
- let mergeData = param.mergeData;
1213
- let chunkParam = param.chunkParam;
1214
- let fullFile = chunkParam.fullFile;
1215
- let mergeUrl = USER_PREFIX + "/excel_import/mergeChunk";
1216
- let target = this.$refs.upload;
1217
- this.$http({
1218
- url: mergeUrl,
1219
- method: "post",
1220
- data: mergeData,
1221
- // failMsg: false,
1222
- modal: false,
1223
- cancelToken: new axios.CancelToken(function executor(c) {
1224
- if (fullFile) fullFile.abort = c;
1225
- }),
1226
- callback: (res) => {
1227
- if (res.type === "success") {
1228
- that.loadingPercent = 100;
1229
- // that.loadingTitle = this.getUploadText(100);
1230
- this.changeUploadPercent(100);
1231
- setTimeout(() => {
1232
- this.checkImportData();
1233
- }, 100);
1234
- } else {
1235
- this.dialogClose2(0);
1236
- }
1237
- },
1238
- error: (e) => {
1239
- console.log(err);
1240
- this.dialogClose2(0);
1241
- },
1242
- });
1243
- },
1244
- getCheckText(percent) {
1245
- return this.$t1("校验导入文件中的图片数据格式 {percent}%", { percent });
1246
- },
1247
- changeCheckTextPercent(percent) {
1248
- this.percent2 = percent;
1249
- this.loadingIndex = 2;
1250
- },
1251
- checkImportData() {
1252
- if (!this.showImportDialog2) return;
1253
- let that = this;
1254
- that.loadingPercent = 0;
1255
- // that.loadingTitle = this.getCheckText(0);
1256
- that.changeCheckTextPercent(0);
1257
- let fullFile = this.fileRaw;
1258
- let chunkParam = fullFile.chunkParam;
1259
-
1260
- this.$http({
1261
- url: USER_PREFIX + "/excel_import/checkData",
1262
- method: "post",
1263
- data: {
1264
- name: chunkParam.name,
1265
- md5: chunkParam.md5,
1266
- uuid: chunkParam.uuid,
1267
- },
1268
- // failMsg: false,
1269
- modal: false,
1270
- cancelToken: new axios.CancelToken(function executor(c) {
1271
- if (fullFile) fullFile.abort = c;
1272
- }),
1273
- onUploadProgress: (progressEvent) => {
1274
- let percent = Math.floor(
1275
- (progressEvent.loaded * 100) / progressEvent.total
1276
- );
1277
- if (percent === 100) {
1278
- percent = 99;
1279
- }
1280
- that.loadingPercent = percent;
1281
- // that.$set(that, 'loadingTitle', this.getCheckText(percent))
1282
- that.changeCheckTextPercent(percent);
1283
- },
1284
- callback: (res) => {
1285
- if (res.type === "success") {
1286
- that.loadingPercent = 100;
1287
- // that.loadingTitle = this.getCheckText(100);
1288
- that.changeCheckTextPercent(100);
1289
- this.handleImageData();
1290
- } else {
1291
- this.dialogClose2(0);
1292
- }
1293
- },
1294
- error: (e) => {
1295
- console.log(err);
1296
- this.dialogClose2(0);
1297
- },
1298
- });
1299
- },
1300
- getSaveImageText(percent) {
1301
- return this.$t1("存储导入文件中的图片 {percent}%", { percent });
1302
- },
1303
- changeSaveImageTextPercent(percent) {
1304
- // return this.$t1('存储导入文件中的图片 {percent}%', {percent})
1305
- this.percent3 = percent;
1306
- this.loadingIndex = 3;
1307
- },
1308
- handleImageData() {
1309
- let that = this;
1310
- that.loadingPercent = 0;
1311
- // that.loadingTitle = this.getSaveImageText(0);
1312
- that.changeSaveImageTextPercent(0);
1313
- this.getImportData(0);
1314
- },
1315
- getImportData(index) {
1316
- if (!this.showImportDialog2) return;
1317
- let that = this;
1318
- let rowSize = this.handleRowSize;
1319
- let fullFile = this.fileRaw;
1320
- let chunkParam = fullFile.chunkParam;
1321
- let rowDatas = this.resultData.data;
1322
- let size = rowDatas.length;
1323
- let currentLineNo = index + 1;
1324
- let rowNumber = index + 3;
1325
- let startRow = index + 3;
1326
- let endRow = index + 3 + rowSize - 1;
1327
- this.$http({
1328
- url: USER_PREFIX + "/excel_import/getData",
1329
- method: "post",
1330
- data: {
1331
- name: chunkParam.name,
1332
- md5: chunkParam.md5,
1333
- uuid: chunkParam.uuid,
1334
- startRow: startRow,
1335
- endRow: endRow,
1336
- },
1337
- // failMsg: false,
1338
- modal: false,
1339
- cancelToken: new axios.CancelToken(function executor(c) {
1340
- if (fullFile) fullFile.abort = c;
1341
- }),
1342
- callback: (res) => {
1343
- if (res.type === "success") {
1344
- let rows = res?.objx?.datas || [];
1345
- let fileCellFields = this.fileCellFields;
1346
- rows.forEach((row) => {
1347
- let rowIndex = row.row - 3;
1348
- let item = rowDatas[rowIndex];
1349
- Object.keys(row).forEach((key) => {
1350
- if (fileCellFields.includes(key)) {
1351
- let value = row[key] || [];
1352
- if (!Array.isArray(value)) {
1353
- value = [value];
1354
- }
1355
- item[key] = value;
1356
- }
1357
- });
1358
- });
1359
- let cIndex = index + rowSize - 1;
1360
- let percent = Math.floor(((cIndex + 1) * 100) / size);
1361
- that.loadingPercent = percent;
1362
- // that.loadingTitle = this.getSaveImageText(percent);
1363
- that.changeSaveImageTextPercent(percent);
1364
- if (cIndex + 1 < size) {
1365
- this.getImportData(cIndex + 1);
1366
- } else {
1367
- this.fileUploadCallback();
1368
- }
1369
- } else {
1370
- this.dialogClose2(0);
1371
- }
1372
- },
1373
- error: (e) => {
1374
- this.dialogClose2(0);
1375
- },
1376
- });
1377
- },
1378
- async generateNewExcel() {
1379
- let file = this.fileRaw;
1380
- try {
1381
- // 1. 读取原始文件
1382
- const workbook = XLSX.read(file, { type: "binary" });
1383
- const sheetName = workbook.SheetNames[0];
1384
- const rawData = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
1385
-
1386
- // 2. 提取表头和数据
1387
- const headers = rawData.slice(0, this.headerRows);
1388
- const bodyData = rawData.slice(this.headerRows);
1389
-
1390
- let exporLineNos = [];
1391
- if (this.resultType) {
1392
- exporLineNos = this.successRows.map((item) => item.impNumber - 1);
1393
- } else {
1394
- exporLineNos = this.failRows.map((item) => item.impNumber - 1);
1395
- }
1396
- // 3. 应用筛选规则
1397
- let selectRule = (row, index) => {
1398
- return exporLineNos.includes(index);
1399
- };
1400
- const filteredData = bodyData.filter(
1401
- (row, index) => {
1402
- return selectRule(row, index + this.headerRows);
1403
- }
1404
- // this.selectRule(row, index + this.headerRows) // 注意索引转换
1405
- );
1406
-
1407
- // 4. 合并数据
1408
- const newData = [...headers, ...filteredData];
1409
-
1410
- // 5. 生成新文件
1411
- const newWorkbook = XLSX.utils.book_new();
1412
- const newSheet = XLSX.utils.aoa_to_sheet(newData);
1413
- XLSX.utils.book_append_sheet(newWorkbook, newSheet, "Sheet1");
1414
-
1415
- // 6. 下载文件
1416
- const blob = XLSX.write(newWorkbook, {
1417
- bookType: "xlsx",
1418
- type: "array",
1419
- });
1420
-
1421
- const url = URL.createObjectURL(blob);
1422
- const a = document.createElement("a");
1423
- a.href = url;
1424
- let fileName = null;
1425
- if (this.resultType) {
1426
- fileName = `导入结果(成功).xlsx`;
1427
- } else {
1428
- fileName = `导入结果(失败).xlsx`;
1429
- }
1430
- a.download = fileName;
1431
- a.click();
1432
-
1433
- // 7. 更新进度
1434
- this.progress = 100;
1435
- setTimeout(() => (this.progress = 0), 1000);
1436
- } catch (error) {
1437
- console.error("处理文件时出错:", error);
1438
- }
1439
- },
1440
- //end
1441
- getLoadingClass(flag, percent) {
1442
- let classStr = null;
1443
- let loadingIndex = this.loadingIndex;
1444
- if (percent >= 100) {
1445
- classStr = "ok";
1446
- } else if (flag === loadingIndex) {
1447
- classStr = "loading";
1448
- }
1449
- return classStr;
1450
- },
1451
-
1452
- /***sheet1 */
1453
- async readExcel2(file, callback) {
1454
- let that = this;
1455
- let option = this.option;
1456
-
1457
- const fileReader = new FileReader();
1458
- fileReader.onload = async (ev) => {
1459
- let resultData;
1460
- try {
1461
- const data = ev.target.result;
1462
- const workbook = configUtil.XLSX.read(data, {
1463
- type: "binary",
1464
- });
1465
-
1466
- let sheetDatas = [];
1467
- for (let pi = 0; pi < workbook.SheetNames.length; pi++) {
1468
- let sheetName = workbook.SheetNames[pi];
1469
- let sheet = workbook.Sheets[sheetName];
1470
-
1471
- if (sheet["!ref"] === undefined || sheet["!ref"] === null) {
1472
- that.$baseAlert(
1473
- this.$t2(
1474
- "请使用正确的导入模版!",
1475
- "components.excelImport.warmMsg2"
1476
- )
1477
- );
1478
- that.handleClose2();
1479
- return false;
1480
- }
1481
- let range = configUtil.XLSX.utils.decode_range(sheet["!ref"]);
1482
- let dataSize = range.e.r + 1; //行数
1483
- that.dataSize = dataSize - 3 >= 0 ? dataSize - 3 : 0;
1484
- let titles = [];
1485
- let fields = [];
1486
-
1487
- const ws = workbook.Sheets[sheet];
1488
-
1489
- let prefix = option.prefix;
1490
- let excelUrl = option.excel;
1491
-
1492
- let excelRows = [];
1493
- let row;
1494
- let rowNum;
1495
- let colNum;
1496
- for (rowNum = range.s.r; rowNum <= range.e.r; rowNum++) {
1497
- row = [];
1498
- for (colNum = range.s.c; colNum <= range.e.c; colNum++) {
1499
- let nextCell =
1500
- sheet[
1501
- configUtil.XLSX.utils.encode_cell({
1502
- r: rowNum,
1503
- c: colNum,
1504
- })
1505
- ];
1506
- if (typeof nextCell === "undefined") {
1507
- row.push(void 0);
1508
- } else {
1509
- row.push(nextCell.w.trim());
1510
- }
1511
- }
1512
- if (rowNum === 1) {
1513
- titles = row;
1514
- }
1515
- if (rowNum === 2) {
1516
- fields = row;
1517
- let checkResult = true;
1518
- }
1519
- if (rowNum > 2) {
1520
- let item = {};
1521
- for (let i = 0; i < fields.length; i++) {
1522
- let field = fields[i];
1523
- if (field) {
1524
- item[field] = row[i] ?? null;
1525
- }
1526
- }
1527
- excelRows.push(item);
1528
- }
1529
- }
1530
- if (
1531
- !titles.length ||
1532
- !fields.length ||
1533
- titles.length !== fields.length
1534
- ) {
1535
- that.$baseAlert(
1536
- this.$t2(
1537
- "请使用正确的导入模版!",
1538
- "components.excelImport.warmMsg2"
1539
- )
1540
- );
1541
- // that.handleClose2();
1542
- return false;
1543
- }
1544
-
1545
- let columns = [];
1546
- let cols = [];
1547
- let uniqueFields = [];
1548
- let uniqueKeys = [];
1549
- for (let i = 0; i < titles.length; i++) {
1550
- let title = titles[i];
1551
- if (title) {
1552
- let field = fields[i];
1553
- if (field === null || field === undefined) {
1554
- that.$baseAlert(
1555
- this.$t2(
1556
- "请使用正确的导入模版!",
1557
- "components.excelImport.warmMsg2"
1558
- )
1559
- );
1560
- // that.handleClose2();
1561
- return false;
1562
- }
1563
- let t = title.substr(-1);
1564
- let u = title.length >= 2 ? title.substr(-2) : title;
1565
- let p = title.length >= 3 ? title.substr(-3) : title;
1566
- let isNeed = false;
1567
- if (t === "*") {
1568
- isNeed = true;
1569
- }
1570
- let isUnique = false;
1571
- /* if (u === "**") {
1572
- uniqueFields.push(field);
1573
- isUnique = true;
1574
- } */
1575
- let isSheetUnique = false;
1576
- if (p === "***") {
1577
- uniqueKeys.push(field);
1578
- isSheetUnique = true;
1579
- }
1580
- if (!uniqueKeys.length) {
1581
- // that.clearImportTimer();
1582
- that.$baseAlert(
1583
- `[${sheetName}]` + that.$t1("缺失单据唯一标识***")
1584
- );
1585
- // that.handleClose2();
1586
- return false;
1587
- }
1588
-
1589
- let otherConfig = {};
1590
- let isFile = false;
1591
- if (field.startsWith("attachments_")) {
1592
- that.fileCellFields.push(field);
1593
- isFile = true;
1594
- otherConfig = {
1595
- slots: {
1596
- default: "attachment",
1597
- },
1598
- };
1599
- }
1600
-
1601
- let col = {
1602
- field: field,
1603
- title: title,
1604
- width: 100,
1605
- isNeed: isNeed,
1606
- isUnique: isUnique,
1607
- isFile,
1608
- otherConfig,
1609
- isSheetUnique,
1610
- };
1611
- cols.push(col);
1612
- }
1613
- }
1614
-
1615
- let oriCols = JSON.parse(JSON.stringify(cols)); //列信息
1616
- /* if (uniqueKeys.length) {
1617
- //分组唯一字段为空时,全部不发包。
1618
- for (let i = 0; i < oriCols.length; i++) {
1619
- let oriCol = oriCols[i];
1620
- if (uniqueKeys.includes(oriCol.field)) {
1621
- for (let j = 0; j < excelRows.length; j++) {
1622
- let data = excelRows[j];
1623
- let value = data[oriCol.field];
1624
- if (value === null || value === undefined || value === "") {
1625
- that.errorHandle(`[${sheetName}]`+
1626
- that.$t2(
1627
- "第" + (j + 4) + "行[" + oriCol.title + "]不能为空;",
1628
- "components.excelImport.warmMsg3",
1629
- {
1630
- lineNo: j + 4,
1631
- title: oriCol.title,
1632
- }
1633
- ));
1634
- return false;
1635
- }
1636
- }
1637
- }
1638
- }
1639
- } */
1640
- // this.oriCols = oriCols;
1641
-
1642
- let resultData1 = {
1643
- sheetName: sheetName,
1644
- data: excelRows,
1645
- titles: titles,
1646
- fields: fields,
1647
- uniqueFields: uniqueFields,
1648
- oriCols: oriCols,
1649
- uniqueKeys,
1650
- };
1651
- sheetDatas.push(resultData1);
1652
- }
1653
-
1654
- //校验必填
1655
- if (!that.checkAllSheetData(sheetDatas)) {
1656
- return false;
1657
- }
1658
-
1659
- //合并多sheet数据
1660
- let newDatas = [];
1661
- resultData = that.$baseLodash.cloneDeep(sheetDatas[0]);
1662
- let uniqueKey = resultData.uniqueKeys[0];
1663
- let data2 = [];
1664
- for (let i = 0; i < resultData.data.length; i++) {
1665
- let item = resultData.data[i];
1666
- let sheetName = resultData[sheetName];
1667
- let uniqueValue = item[uniqueKey];
1668
-
1669
- if (!that.isNull(uniqueValue)) {
1670
- let newItem = { ...item };
1671
- let allItems = [];
1672
- for (let j = 1; j < sheetDatas.length; j++) {
1673
- let sheetData = sheetDatas[j];
1674
- let fDatas = [];
1675
- for (let k = 0; k < sheetData.data.length; k++) {
1676
- let sheetItem = sheetData.data[k];
1677
- if (that.isNull(sheetItem[uniqueKey])) {
1678
- that.handleCellNotNull(k, sheetData);
1679
- return;
1680
- }
1681
- if (sheetItem[uniqueKey] === uniqueValue) {
1682
- fDatas.push(sheetItem);
1683
- }
1684
- }
1685
- allItems.push(fDatas);
1686
- }
1687
- newItem.sheetItems = allItems;
1688
- data2.push(newItem);
1689
- } else {
1690
- that.handleCellNotNull(i, resultData);
1691
- return false;
1692
- }
1693
- }
1694
-
1695
- resultData.sheetDatas = sheetDatas;
1696
- resultData.data = data2;
1697
- this.oriCols = resultData.oriCols;
1698
- this.resultData = resultData;
1699
- callback(resultData);
1700
- } catch (et) {
1701
- that.showContent = false;
1702
- that.clearImportTimer();
1703
- console.error(et);
1704
- }
1705
- };
1706
- fileReader.readAsBinaryString(file);
1707
- },
1708
- isNull(val) {
1709
- if (val === null || val === undefined || val === "" || val === undefined || val === null) {
1710
- return true;
1711
- }
1712
- },
1713
- checkAllSheetData(sheetItems){
1714
- let that = this;
1715
- for(let sheetItem of sheetItems){
1716
- let oriCols = sheetItem.oriCols;
1717
- let uniqueKeys = sheetItem.uniqueKeys;
1718
- let excelRows = sheetItem.data;
1719
- let sheetName = sheetItem.sheetName;
1720
-
1721
- for (let i = 0; i < oriCols.length; i++) {
1722
- let oriCol = oriCols[i];
1723
- if (oriCol.isNeed || uniqueKeys.includes(oriCol.field)) {
1724
- for (let j = 0; j < excelRows.length; j++) {
1725
- let data = excelRows[j];
1726
- let value = data[oriCol.field];
1727
- if (that.isNull(value)) {
1728
- that.errorHandle(`[${sheetName}]`+
1729
- that.$t2(
1730
- "第" + (j + 4) + "行[" + oriCol.title + "]不能为空;",
1731
- "components.excelImport.warmMsg3",
1732
- {
1733
- lineNo: j + 4,
1734
- title: oriCol.title,
1735
- }
1736
- ));
1737
- return false;
1738
- }
1739
- }
1740
- }
1741
- }
1742
-
1743
- }
1744
- return true;
1745
- },
1746
-
1747
-
1748
- handleCellNotNull(i, sheetData) {
1749
- let that = this;
1750
- let uniqueKey = sheetData.uniqueKeys[0];
1751
- let oriCol = sheetData.oriCols.find((item) => item.field === uniqueKey);
1752
- that.errorHandle(
1753
- `[${sheetData.sheetName}]` +
1754
- that.$t2(
1755
- "第" + (i + 4) + "行[" + oriCol.title + "]不能为空;",
1756
- "components.excelImport.warmMsg3",
1757
- {
1758
- lineNo: i + 4,
1759
- title: oriCol.title,
1760
- }
1761
- )
1762
- );
1763
- },
1764
- errorHandle(errorText) {
1765
- this.clearImportTimer();
1766
- this.$baseAlert(errorText);
1767
- // this.handleClose2();
1768
- },
1769
- /***sheet2 */
1770
- },
1771
- };
1772
- export const mixins = tmixins;
1
+ /**version-1.0*/
2
+ import { read, utils } from "xlsx";
3
+ import axios from "axios";
4
+ import SparkMD5 from "spark-md5";
5
+
6
+ let tmixins = {};
7
+ let XLSX = window.XLSX || { read, utils };
8
+ import { getToken } from "../../../../../utils/auth";
9
+ import XEUtils from "xe-utils";
10
+ import { getErrorMsg } from "@base/utils/index.js";
11
+
12
+ let configUtil = {
13
+ baseUrl: process.env.VUE_APP_BASE_API,
14
+ XLSX,
15
+ getToken,
16
+ };
17
+ // importTimer / loadingObj 原为模块级单例:两个导入弹窗并存时后者覆盖前者引用,
18
+ // 前一个 interval(100ms/次)与 loading 永久失控——已改为实例属性 this.importTimer / this.loadingObj
19
+ tmixins = {
20
+ name: "excelImport",
21
+ props: ["param", "parentTarget"],
22
+ inject: ["getReportTemplate", "formHttp"],
23
+ data() {
24
+ return {
25
+ excTime: 0,
26
+ showImportDialog: false,
27
+ showImportDialog2: false,
28
+ falseValue: false,
29
+ fileRaw: false,
30
+ isEnd: false,
31
+ currentIndex: 0,
32
+ excelTemplate: "",
33
+ prefix: "/user",
34
+ dataSize: 0,
35
+ totalSuccessNum: 0,
36
+ totalErrorNum: 0,
37
+ percentageNum: 0,
38
+ successRows: [],
39
+ failRows: [],
40
+ oriCols: [],
41
+ showImportResult: false,
42
+ resultType: "",
43
+ option: {},
44
+ showContent: false,
45
+ resOption: {},
46
+ fileCellFields: [],
47
+ importLoading: false,
48
+ loadingTitle: null,
49
+
50
+ percent1: 0,
51
+ percent2: 0,
52
+ percent3: 0,
53
+
54
+ loadingPercent: 0,
55
+ handleRowSize: 1,
56
+
57
+ headerRows: 3,
58
+ };
59
+ },
60
+ computed: {
61
+ importFileLimitSize() {
62
+ return Math.min(
63
+ this.param?.importOption?.importFileLimitSize || 200,
64
+ 200
65
+ );
66
+ },
67
+ },
68
+ created() {
69
+ this.exc();
70
+ },
71
+ beforeDestroy() {
72
+ this.clearImportTimer();
73
+ },
74
+ methods: {
75
+ initResGird() {
76
+ let that = this;
77
+ let tableRef = "resGrid";
78
+ let columns = [
79
+ {
80
+ type: "checkbox",
81
+ fixed: "left",
82
+ width: 48,
83
+ resizable: false,
84
+ headerClassName: "vxe-hcs",
85
+ className: "vxe-hcs",
86
+ },
87
+ {
88
+ field: "impNumber",
89
+ title: this.$t2("行号", "components.excelImport.impNumber"),
90
+ width: 100,
91
+ fixed: "left",
92
+ },
93
+ {
94
+ field: "_resultContent",
95
+ title: this.$t2("结果", "components.excelImport.resultContent"),
96
+ width: 250,
97
+ fixed: "left",
98
+ slots: {
99
+ default: ({ row, $rowIndex, $table }) => {
100
+ return that.handleRes(row._resultContent);
101
+ },
102
+ },
103
+ },
104
+ ];
105
+ let cCols = this.oriCols.map((oriCol, index) => {
106
+ let col = {
107
+ field: oriCol.field,
108
+ title: oriCol.title,
109
+ width: 150,
110
+ ...oriCol.otherConfig,
111
+ };
112
+ if (index === 0) {
113
+ col.fixed = "left";
114
+ }
115
+ return col;
116
+ });
117
+ columns = columns.concat(cCols);
118
+
119
+ let tableOption = {
120
+ vue: this,
121
+ tableRef: tableRef,
122
+ tableNameRequired: false,
123
+ columns: columns,
124
+ config: {
125
+ toolbarConfig: {
126
+ custom: false,
127
+ },
128
+ },
129
+ };
130
+
131
+ this.$vxeTableUtil.initVxeTable(tableOption).then((opts) => {
132
+ this.resOption = opts;
133
+ });
134
+ },
135
+ exc() {
136
+ this.option = this.param;
137
+ this.showContent = true;
138
+ this.showImportDialog = true;
139
+ this.showImportDialog2 = false;
140
+ },
141
+ showSuccessResult() {
142
+ this.showImportResult = true;
143
+ this.resultType = 1;
144
+ this.$nextTick(() => {
145
+ this.initResGird();
146
+ this.$nextTick(() => {
147
+ let tDatas = this.successRows.map((item, index) => {
148
+ item.id = index;
149
+ return item;
150
+ });
151
+ this.$refs.resGrid.loadData(tDatas);
152
+ });
153
+ });
154
+ },
155
+ showErrorResult() {
156
+ this.showImportResult = true;
157
+ this.resultType = 0;
158
+ this.$nextTick(() => {
159
+ this.initResGird();
160
+ this.$nextTick(() => {
161
+ let tDatas = this.failRows.map((item, index) => {
162
+ item.id = index;
163
+ return item;
164
+ });
165
+ this.$refs.resGrid.loadData(tDatas);
166
+ });
167
+ });
168
+ },
169
+ fileChange(file) {
170
+ if (file) {
171
+ this.fileRaw = file.raw;
172
+ } else {
173
+ this.fileRaw = false;
174
+ }
175
+ },
176
+ dialogClose1() {
177
+ this.importLoading = false;
178
+ if (!this.showImportDialog2) {
179
+ this.$emit("update:visiable", false);
180
+ this.showContent = false;
181
+ }
182
+ },
183
+ async dialogPrimary1() {
184
+ let that = this;
185
+ let option = this.option;
186
+
187
+ let fileRaw = this.fileRaw;
188
+ if (!fileRaw) {
189
+ this.$baseAlert(
190
+ this.$t2("请上传附件", "components.excelImport.warmMsg1")
191
+ );
192
+ return false;
193
+ }
194
+ let importFileLimitSize = this.importFileLimitSize;
195
+ let fileSize = fileRaw.size;
196
+ let limitSize = importFileLimitSize * 1024 * 1024;
197
+ if (fileSize > limitSize) {
198
+ this.$baseAlert(
199
+ this.$t1("导入文件不允许超过{fileSize}MB", {
200
+ fileSize: importFileLimitSize,
201
+ })
202
+ );
203
+ return false;
204
+ }
205
+
206
+ if (option.importFrontOnly) {
207
+ this.dialogPrimary3();
208
+ return false;
209
+ }
210
+
211
+ /* this.createImportTimer();
212
+ this.showImportDialog = false;
213
+ if (!option.onConfirm) {
214
+ this.showImportDialog2 = true;
215
+ } */
216
+ // this.$nextTick(() => {
217
+ try {
218
+ this.readExcel(this.fileRaw, function (resultData) {
219
+ that.createImportTimer();
220
+ that.showImportDialog = false;
221
+ if (!option.onConfirm) {
222
+ that.showImportDialog2 = true;
223
+ }
224
+ that.$nextTick(() => {
225
+ if (option.onConfirm) {
226
+ option.onConfirm(resultData.data, that.fileRaw);
227
+ } else {
228
+ that.handleBeforeImport0(that.fileRaw, resultData, () => {
229
+ that.syncDataForImport({
230
+ multi: false,
231
+ data: resultData,
232
+ // saveUrl: saveUrl
233
+ });
234
+ });
235
+ }
236
+ });
237
+ });
238
+ } catch (et) {
239
+ that.clearImportTimer();
240
+ console.error(et);
241
+ }
242
+ // });
243
+ },
244
+ handleBeforeImport(file, resultData, callback) {
245
+ let importOption = this.option.importOption;
246
+ let that = this;
247
+ if (importOption.onBeforeImport) {
248
+ const toDo = (res) => {
249
+ let rows = res?.objx || [];
250
+ rows.forEach((row, rowIndex) => {
251
+ let item = resultData[rowIndex];
252
+ Object.keys(row).forEach((key) => {
253
+ item[key] = row[key];
254
+ });
255
+ });
256
+ callback && callback();
257
+ };
258
+ this.getFieldTarget().handleCustomEvent(
259
+ importOption.onBeforeImport,
260
+ ["file", "resultData", "done"],
261
+ [file, resultData, toDo]
262
+ );
263
+ } else {
264
+ callback && callback();
265
+ }
266
+ },
267
+ handleBeforeImport0(file, resultData, callback) {
268
+ if (!this.showImportDialog2) return;
269
+ let importOption = this.option.importOption;
270
+ if (!importOption.enabledImportPreHandle) {
271
+ this.handleBeforeImport(file, resultData, () => {
272
+ callback && callback();
273
+ });
274
+ return;
275
+ }
276
+
277
+ this.uploadFile(() => {
278
+ this.importLoading = false;
279
+ this.handleBeforeImport(file, resultData, () => {
280
+ callback && callback();
281
+ });
282
+ });
283
+ return;
284
+ },
285
+ handleBeforeClose(hide) {
286
+ this.option.onCancel &&
287
+ this.option.onCancel(this.getCallbackData(), this.fileRaw);
288
+ let importOption = this.option.importOption;
289
+ this.getFieldTarget().handleCustomEvent(
290
+ importOption.onSuccessImport,
291
+ ["resultData", "file"],
292
+ [this.getCallbackData(), this.fileRaw]
293
+ );
294
+ this.handleTableCallback();
295
+ hide();
296
+ },
297
+ dialogClose2() {
298
+ this.showImportDialog2 = false;
299
+ this.option.onBeforeCancel &&
300
+ this.option.onBeforeCancel(this.getCallbackData(), this.fileRaw);
301
+ let importOption = this.option.importOption;
302
+ this.getFieldTarget().handleCustomEvent(
303
+ importOption.onSuccessImport,
304
+ ["resultData", "file"],
305
+ [this.getCallbackData(), this.fileRaw]
306
+ );
307
+ this.handleTableCallback();
308
+ },
309
+ handleClose2() {
310
+ this.clearImportTimer();
311
+ this.showImportDialog2 = false;
312
+ this.showContent = false;
313
+ this.option.onClose &&
314
+ this.option.onClose(this.getCallbackData(), this.fileRaw);
315
+ this.option.callback &&
316
+ this.option.callback(this.getCallbackData(), this.fileRaw);
317
+ this.dialogClose1();
318
+ },
319
+ dialogPrimary2() {
320
+ let importOption = this.option.importOption;
321
+ this.showImportDialog2 = false;
322
+ this.option.onBeforeConfirm &&
323
+ this.option.onBeforeConfirm(this.getCallbackData(), this.fileRaw);
324
+ this.getFieldTarget().handleCustomEvent(
325
+ importOption.onSuccessImport,
326
+ ["resultData", "file"],
327
+ [this.getCallbackData(), this.fileRaw]
328
+ );
329
+ this.handleTableCallback();
330
+ },
331
+ getCallbackData() {
332
+ return {
333
+ ...this.resultData,
334
+ successRows: this.successRows,
335
+ failRows: this.failRows,
336
+ };
337
+ },
338
+
339
+ /*dialogClose2(flag) {
340
+ let importOption = this.option.importOption;
341
+ this.clearImportTimer();
342
+ this.showImportDialog2 = false;
343
+ this.dialogClose1();
344
+ this.handleTableCallback(flag);
345
+ this.parentTarget.handleCustomEvent(importOption.onSuccessImport, ['resultData', 'file'], [this.resultData, this.fileRaw])
346
+ this.option.callback && this.option.callback(this.resultData, this.fileRaw);
347
+ },
348
+ dialogPrimary2() {
349
+ let importOption = this.option.importOption;
350
+ this.clearImportTimer();
351
+ this.showImportDialog2 = false;
352
+ this.dialogClose1()
353
+ this.handleTableCallback();
354
+ let fileRaw = this.fileRaw;
355
+ this.parentTarget.handleCustomEvent(importOption.onSuccessImport, ['resultData', 'file'], [this.resultData, this.fileRaw])
356
+ this.option.callback && this.option.callback(this.resultData, this.fileRaw);
357
+ },*/
358
+ handleTableCallback(flag) {
359
+ if (flag === 0) return;
360
+ let importOption = this.option.importOption;
361
+ let tableTarget;
362
+ if (importOption.tableRef)
363
+ tableTarget = this.getFieldTarget().getWidgetRef(importOption.tableRef);
364
+ if (tableTarget) {
365
+ let isQueryTable = tableTarget.widget.options.isQueryTable;
366
+ if (isQueryTable) {
367
+ tableTarget.searchEvent();
368
+ }
369
+ }
370
+ },
371
+ async readExcel(file, callback) {
372
+ let that = this;
373
+ let option = this.option;
374
+
375
+ if (option.importOption.multipleSheet) {
376
+ this.readExcel2(file, callback);
377
+ return;
378
+ }
379
+
380
+ const fileReader = new FileReader();
381
+ fileReader.onload = async (ev) => {
382
+ let resultData;
383
+ try {
384
+ const data = ev.target.result;
385
+ const workbook = configUtil.XLSX.read(data, {
386
+ type: "binary",
387
+ });
388
+
389
+ let sheet = workbook.Sheets[workbook.SheetNames[0]];
390
+ if (sheet["!ref"] === undefined || sheet["!ref"] === null) {
391
+ /*that.showImportDialog2 = false;
392
+ that.showContent = false;
393
+ that.clearImportTimer();*/
394
+ that.$baseAlert(
395
+ this.$t2(
396
+ "请使用正确的导入模版!",
397
+ "components.excelImport.warmMsg2"
398
+ )
399
+ );
400
+ that.handleClose2();
401
+ return false;
402
+ }
403
+ let range = configUtil.XLSX.utils.decode_range(sheet["!ref"]);
404
+ let dataSize = range.e.r + 1; //行数
405
+ that.dataSize = dataSize - 3 >= 0 ? dataSize - 3 : 0;
406
+ let titles = [];
407
+ let fields = [];
408
+
409
+ const ws = workbook.Sheets[sheet];
410
+
411
+ let prefix = option.prefix;
412
+ let excelUrl = option.excel;
413
+
414
+ let excelRows = [];
415
+ let row;
416
+ let rowNum;
417
+ let colNum;
418
+ for (rowNum = range.s.r; rowNum <= range.e.r; rowNum++) {
419
+ row = [];
420
+ for (colNum = range.s.c; colNum <= range.e.c; colNum++) {
421
+ let nextCell =
422
+ sheet[
423
+ configUtil.XLSX.utils.encode_cell({
424
+ r: rowNum,
425
+ c: colNum,
426
+ })
427
+ ];
428
+ if (typeof nextCell === "undefined") {
429
+ row.push(void 0);
430
+ } else {
431
+ row.push(nextCell.w.trim());
432
+ }
433
+ }
434
+ if (rowNum === 1) {
435
+ titles = row;
436
+ }
437
+ if (rowNum === 2) {
438
+ fields = row;
439
+ let checkResult = true;
440
+ /*await that.checkExcelForImport(titles, fields, excelUrl, prefix).then(
441
+ res => {
442
+ if (res.type !== "success") {
443
+ checkResult = false;
444
+ }
445
+ });
446
+ if (!checkResult) {
447
+ that.showContent = false;
448
+ that.clearImportTimer();
449
+ return false;
450
+ }*/
451
+ }
452
+ if (rowNum > 2) {
453
+ let item = {};
454
+ for (let i = 0; i < fields.length; i++) {
455
+ let field = fields[i];
456
+ if (field) {
457
+ item[field] = row[i] ?? null;
458
+ }
459
+ }
460
+ excelRows.push(item);
461
+ }
462
+ }
463
+ if (
464
+ !titles.length ||
465
+ !fields.length ||
466
+ titles.length !== fields.length
467
+ ) {
468
+ // that.showContent = false;
469
+ // that.clearImportTimer();
470
+ that.$baseAlert(
471
+ this.$t2(
472
+ "请使用正确的导入模版!",
473
+ "components.excelImport.warmMsg2"
474
+ )
475
+ );
476
+ that.handleClose2();
477
+ return false;
478
+ }
479
+
480
+ let columns = [];
481
+ let cols = [];
482
+ let uniqueFields = [];
483
+ for (let i = 0; i < titles.length; i++) {
484
+ let title = titles[i];
485
+ if (title) {
486
+ let field = fields[i];
487
+ if (field === null || field === undefined) {
488
+ // that.showContent = false;
489
+ // that.clearImportTimer();
490
+ that.$baseAlert(
491
+ this.$t2(
492
+ "请使用正确的导入模版!",
493
+ "components.excelImport.warmMsg2"
494
+ )
495
+ );
496
+ that.handleClose2();
497
+ return false;
498
+ }
499
+ let t = title.substr(-1);
500
+ let u = title.length >= 2 ? title.substr(-2) : title;
501
+ let isNeed = false;
502
+ if (t === "*") {
503
+ isNeed = true;
504
+ }
505
+ let isUnique = false;
506
+ if (u === "**") {
507
+ uniqueFields.push(field);
508
+ isUnique = true;
509
+ }
510
+
511
+ let otherConfig = {};
512
+ let isFile = false;
513
+ if (field.startsWith("attachments_")) {
514
+ that.fileCellFields.push(field);
515
+ isFile = true;
516
+ otherConfig = {
517
+ slots: {
518
+ default: "attachment",
519
+ },
520
+ };
521
+ }
522
+
523
+ let col = {
524
+ field: field,
525
+ title: title,
526
+ width: 100,
527
+ isNeed: isNeed,
528
+ isUnique: isUnique,
529
+ isFile,
530
+ otherConfig,
531
+ };
532
+ cols.push(col);
533
+ }
534
+ }
535
+
536
+ let oriCols = JSON.parse(JSON.stringify(cols)); //列信息
537
+ if (uniqueFields.length) {
538
+ //分组唯一字段为空时,全部不发包。
539
+ for (let i = 0; i < oriCols.length; i++) {
540
+ let oriCol = oriCols[i];
541
+ if (oriCol.isNeed) {
542
+ for (let j = 0; j < excelRows.length; j++) {
543
+ let data = excelRows[j];
544
+ let value = data[oriCol.field];
545
+ if (value === null || value === undefined || value === "") {
546
+ that.clearImportTimer();
547
+ that.$baseAlert(
548
+ this.$t2(
549
+ "第" + (j + 4) + "行[" + oriCol.title + "]不能为空;",
550
+ "components.excelImport.warmMsg3",
551
+ {
552
+ lineNo: j + 4,
553
+ title: oriCol.title,
554
+ }
555
+ )
556
+ );
557
+ that.handleClose2();
558
+ return false;
559
+ }
560
+ }
561
+ }
562
+ }
563
+ }
564
+
565
+ this.oriCols = oriCols;
566
+
567
+ resultData = {
568
+ data: excelRows,
569
+ titles: titles,
570
+ fields: fields,
571
+ uniqueFields: uniqueFields,
572
+ oriCols: oriCols,
573
+ };
574
+ this.resultData = resultData;
575
+ callback(resultData);
576
+ } catch (et) {
577
+ that.showContent = false;
578
+ that.clearImportTimer();
579
+ console.error(et);
580
+ }
581
+ };
582
+ fileReader.readAsBinaryString(file);
583
+ },
584
+ async checkExcelForImport(titles, fields, turl, prefix) {
585
+ if (!this.showImportDialog2) return;
586
+ let that = this;
587
+ let data = {
588
+ filed_name: fields,
589
+ field_note: titles,
590
+ url: turl,
591
+ };
592
+ let param = JSON.stringify(data);
593
+ return this.$http({
594
+ url: prefix + "/sf_common/compareExcelFields",
595
+ method: "post",
596
+ headers: {
597
+ "Content-Type": "application/json;charset=utf-8",
598
+ },
599
+ // data: param,
600
+ data: data,
601
+ });
602
+ },
603
+ saveImportHandle(data, opt) {
604
+ let multi = this.option.multi;
605
+ let importOption = this.option.importOption;
606
+
607
+ let entity = importOption.importEntity;
608
+
609
+ if (!entity) return;
610
+
611
+ let reportTemplate = this.getReportTemplate();
612
+ let formCode = reportTemplate?.formCode;
613
+ let scriptCode = importOption.importScriptCode || "import";
614
+ // let config = option?.config;
615
+
616
+ // let reqData = this.getReqFormData();
617
+ let fileCellFields = this.fileCellFields;
618
+ let formData = null;
619
+ if (multi) {
620
+ formData = data;
621
+ } else {
622
+ formData = {
623
+ [entity]: { ...data },
624
+ };
625
+ if (fileCellFields.length) {
626
+ fileCellFields.forEach((field) => {
627
+ let attachments = data[field] || [];
628
+ delete formData[entity][field];
629
+ formData[field] = attachments;
630
+ });
631
+ }
632
+ }
633
+
634
+ let reqData = {
635
+ formCode: formCode,
636
+ formVersion: reportTemplate.formVersion,
637
+ taBm: entity,
638
+ data: formData,
639
+ };
640
+
641
+ this.formHttp({
642
+ scriptCode: scriptCode,
643
+ data: reqData,
644
+ modal: false,
645
+ ...opt,
646
+ });
647
+ },
648
+ syncDataForImport(opts) {
649
+ let that = this;
650
+ let multi = this.option.multi;
651
+ let resultData = this.resultData;
652
+ let datas = resultData.data;
653
+ let titles = resultData.titles;
654
+ let fields = resultData.fields;
655
+ let uniqueFields = resultData.uniqueFields;
656
+ let saveUrl = opts.saveUrl;
657
+ let size = datas.length;
658
+ let index = 0;
659
+ let successNum = 0;
660
+ let failNum = 0;
661
+ let dialogObj = this.$refs.importDialog.$el;
662
+ let successNumObj = dialogObj.querySelector(".successNum");
663
+ let failNumObj = dialogObj.querySelector(".failNum");
664
+ let percentageObj = dialogObj.querySelector(".percentage");
665
+ let doneNumObj = dialogObj.querySelector(".doneNum");
666
+ dialogObj.querySelector(".dataSize").innerText = size;
667
+
668
+ that.successRows = [];
669
+ that.failRows = [];
670
+
671
+ let multiSize = this.option.multiSize || 2;
672
+
673
+ let groupIndex = 0;
674
+ let groupDatas = [];
675
+ if (uniqueFields.length) {
676
+ let d = XEUtils.groupBy(datas, function (item, itemIndex, items) {
677
+ let keyArr = [];
678
+ uniqueFields.forEach((field) => {
679
+ keyArr.push(item[field]);
680
+ });
681
+ return keyArr.join("&_&");
682
+ });
683
+ for (let key in d) {
684
+ groupDatas.push(d[key]);
685
+ }
686
+ datas.forEach((item, itemIndex) => {
687
+ item.impSeq = itemIndex;
688
+ item.impNumber = itemIndex + 4;
689
+ });
690
+ }
691
+
692
+ let compareV = function (property) {
693
+ return function (a, b) {
694
+ let value1 = a[property];
695
+ let value2 = b[property];
696
+ return value1 - value2;
697
+ };
698
+ };
699
+
700
+ let prevHandleData = function (percentageStr, excNum) {
701
+ successNumObj.innerText = successNum;
702
+ failNumObj.innerText = failNum;
703
+ doneNumObj.innerText = successNum + failNum;
704
+ that.percentageNum = percentageStr;
705
+ let isEnd = false;
706
+ if (multi && uniqueFields.length) {
707
+ isEnd = groupIndex + 1 >= groupDatas.length;
708
+ } else {
709
+ isEnd = index + excNum >= size;
710
+ }
711
+ if (!isEnd) {
712
+ index = index + excNum;
713
+ groupIndex = groupIndex + 1;
714
+ setTimeout(function () {
715
+ handleData();
716
+ }, 1);
717
+ } else {
718
+ setTimeout(function () {
719
+ that.clearImportTimer();
720
+ }, 300);
721
+ }
722
+ };
723
+
724
+ let getDefaultValue = (row) => {
725
+ let value = null;
726
+ let defaultValue = this.option.defaultValue;
727
+ if (defaultValue) {
728
+ if (typeof defaultValue === "function") {
729
+ value = defaultValue(row) || {};
730
+ } else {
731
+ value = defaultValue || {};
732
+ }
733
+ }
734
+ return value;
735
+ };
736
+
737
+ let handleData = () => {
738
+ if (!that.isEnd && index < size) {
739
+ let param;
740
+ let excNum;
741
+ if (multi) {
742
+ if (!uniqueFields.length) {
743
+ if (index + multiSize < size) {
744
+ excNum = multiSize;
745
+ } else {
746
+ excNum = size - index;
747
+ }
748
+
749
+ let dataList = [];
750
+ for (let i = 0; i < excNum; i++) {
751
+ let mIndex = index + i;
752
+ let mData = datas[mIndex];
753
+ mData.impSeq = mIndex;
754
+ mData.impNumber = mIndex + 4;
755
+
756
+ let errorInfo = that.vailData(mData, opts);
757
+ if (errorInfo.length > 0) {
758
+ mData._resultType = "error";
759
+ mData._resultContent = errorInfo;
760
+ failNum++;
761
+ that.failRows.push(mData);
762
+ } else {
763
+ let defaultValue = getDefaultValue(mData);
764
+ if (defaultValue) {
765
+ Object.assign(mData, defaultValue);
766
+ }
767
+ dataList.push(mData);
768
+ }
769
+
770
+ datas[mIndex] = mData;
771
+ }
772
+ if (dataList.length > 0) {
773
+ param = dataList;
774
+ }
775
+ } else {
776
+ excNum = groupDatas[groupIndex].length;
777
+ param = groupDatas[groupIndex];
778
+ }
779
+ } else {
780
+ let data = that.resultData.data[index];
781
+ data.impSeq = index;
782
+ data.impNumber = index + 4;
783
+ excNum = 1;
784
+ datas[index] = data;
785
+
786
+ let errorInfo = that.vailData(data, opts);
787
+ if (errorInfo.length > 0) {
788
+ data._resultType = "error";
789
+ data._resultContent = errorInfo;
790
+ failNum++;
791
+ that.failRows.push(data);
792
+ } else {
793
+ param = data;
794
+ let defaultValue = getDefaultValue(data);
795
+ if (defaultValue) {
796
+ Object.assign(param, defaultValue);
797
+ }
798
+ }
799
+ }
800
+
801
+ let percentageStr = parseInt(((index + excNum) * 100) / size);
802
+ if (param === null || param === undefined || param.length === 0) {
803
+ if (that.showContent) {
804
+ prevHandleData(percentageStr, excNum);
805
+ }
806
+ return;
807
+ }
808
+
809
+ that.saveImportHandle(param, {
810
+ failMsg: false,
811
+ callback: (resultMsg) => {
812
+ if (multi) {
813
+ if (resultMsg.type === "success") {
814
+ let multiRows = resultMsg.objx;
815
+ for (let i = 0; i < multiRows.length; i++) {
816
+ let multiRow = multiRows[i];
817
+ let data = datas[multiRow.impSeq];
818
+ data._resultType = multiRow.impReturnType;
819
+ data._resultContent =
820
+ multiRow.impReturnType === "success"
821
+ ? this.$t2(
822
+ "导入成功",
823
+ "components.excelImport.importSucess"
824
+ )
825
+ : multiRow.impReturnMsg;
826
+ if (multiRow.impReturnType === "success") {
827
+ successNum++;
828
+ that.successRows.push(data);
829
+ } else {
830
+ failNum++;
831
+ that.failRows.push(data);
832
+ }
833
+ }
834
+
835
+ that.failRows = that.failRows.sort(compareV("impSeq"));
836
+ } else {
837
+ // error_win(resultMsg);
838
+ // layer.close(opts.dialogObjIndex);
839
+
840
+ let items = param.map((item) => {
841
+ return {
842
+ ...item,
843
+ _resultType: "error",
844
+ _resultContent: resultMsg.content,
845
+ };
846
+ });
847
+ failNum = failNum + items.length;
848
+ that.failRows.push(...items);
849
+
850
+ that.failRows = that.failRows.sort(compareV("impSeq"));
851
+
852
+ /* that.$errorMsg(resultMsg);
853
+ that.showContent = false;
854
+ that.clearImportTimer();
855
+ return; */
856
+ }
857
+ } else {
858
+ let data = that.resultData.data[index];
859
+ data._resultType = resultMsg.type;
860
+ data._resultContent =
861
+ resultMsg.type === "success"
862
+ ? this.$t2(
863
+ "导入成功",
864
+ "components.excelImport.importSucess"
865
+ )
866
+ : resultMsg.content;
867
+
868
+ if (resultMsg.type === "success") {
869
+ successNum++;
870
+ that.successRows.push(data);
871
+ } else {
872
+ failNum++;
873
+ that.failRows.push(data);
874
+ }
875
+ }
876
+ if (that.showContent) {
877
+ prevHandleData(percentageStr, excNum);
878
+ }
879
+ },
880
+ error: (et) => {
881
+ that.isEnd = true;
882
+ that.clearImportTimer();
883
+ console.error(et);
884
+ },
885
+ });
886
+ }
887
+ };
888
+ handleData();
889
+ },
890
+ commonLocalDownload() {
891
+ let importOption = this.option.importOption;
892
+ let importAttachCode = importOption.importAttachCode;
893
+ if (!importAttachCode) return;
894
+ this.$http({
895
+ url: USER_PREFIX + "/bd_attach_setting/getByCode",
896
+ method: "post",
897
+ data: {
898
+ stringOne: importAttachCode,
899
+ },
900
+ success: (res) => {
901
+ let fileObj = res.objx;
902
+ let url = fileObj?.url;
903
+ if (fileObj && url) {
904
+ this.$commonFileUtil.downloadFile(url,fileObj.name);
905
+ }
906
+ },
907
+ });
908
+ },
909
+ vailData(data, opts) {
910
+ let oriCols = opts.data.oriCols;
911
+ let errorInfo = [];
912
+ for (let i = 0; i < oriCols.length; i++) {
913
+ let oriCol = oriCols[i];
914
+ if (oriCol.isNeed) {
915
+ let value = data[oriCol.field];
916
+ if (value === null || value === undefined || value === "") {
917
+ errorInfo.push(
918
+ this.$t2(
919
+ "[" + oriCol.title + "]不能为空;",
920
+ "components.excelImport.warmMsg4",
921
+ { title: oriCol.title }
922
+ )
923
+ );
924
+ }
925
+ }
926
+ }
927
+ return errorInfo.join("");
928
+ },
929
+ handleRes(val) {
930
+ /* let content = val;
931
+ let text = content;
932
+ if (content && content.indexOf("Exception") >= 0) {
933
+ let index0 = content.lastIndexOf("*]");
934
+ if (index0 >= 0) {
935
+ text = content.substr(index0);
936
+ if (text) {
937
+ let index1 = text.indexOf("Exception:");
938
+ if (index1 >= 0) {
939
+ text = text.substr(index1 + 10);
940
+ }
941
+ }
942
+ }
943
+ } */
944
+ let text = getErrorMsg(val);
945
+ return text;
946
+ },
947
+ exportToExcel() {
948
+ let str =
949
+ this.resultType === 1
950
+ ? this.$t2("成功", "components.excelImport.success")
951
+ : this.$t2("失败", "components.excelImport.fail");
952
+ let fileName =
953
+ this.$t2("导入结果导出", "components.excelImport.exportFileName") +
954
+ "(" +
955
+ str +
956
+ ")";
957
+ let $grid = this.$refs.resGrid;
958
+ let columns = $grid.getColumns();
959
+ if (columns && columns.length) {
960
+ let fields = columns
961
+ .filter((item, index) => {
962
+ return index > 0 && item.property;
963
+ })
964
+ .map((item, index) => {
965
+ return item.property;
966
+ });
967
+ this.$refs.resGrid.exportData({
968
+ filename: fileName,
969
+ mode: "all",
970
+ type: "csv",
971
+ columns: fields,
972
+ });
973
+ }
974
+ },
975
+ createImportTimer() {
976
+ this.excTime = 0;
977
+ let beginTime = new Date().getTime();
978
+ this.importTimer = setInterval(() => {
979
+ let nowTime = new Date().getTime();
980
+ let diffTime = (nowTime - beginTime) / 1000;
981
+ this.$set(this, "excTime", this.$baseLodash.round(diffTime, 2));
982
+ }, 100);
983
+ },
984
+ clearImportTimer() {
985
+ clearInterval(this.importTimer);
986
+ this.importTimer = null;
987
+ this.loadingObj && this.loadingObj.close();
988
+ this.loadingObj = null;
989
+ },
990
+ getWidgetTarget() {},
991
+ getFieldTarget() {
992
+ return this.param.target;
993
+ },
994
+ async dialogPrimary3() {
995
+ if (!this.fileRaw) {
996
+ this.$baseAlert(
997
+ this.$t2("请上传附件", "components.excelImport.warmMsg1")
998
+ );
999
+ return false;
1000
+ }
1001
+ let that = this;
1002
+ let option = this.option;
1003
+ this.loadingObj = this.$baseLoading({
1004
+ target: document.body,
1005
+ background: "unset",
1006
+ });
1007
+
1008
+ let importOption = option.importOption;
1009
+ this.readExcel(this.fileRaw, function (resultData) {
1010
+ let file = that.fileRaw;
1011
+ let flag = false;
1012
+ let done = () => {
1013
+ if (flag) return;
1014
+ flag = true;
1015
+ that.showImportDialog = false;
1016
+ return that
1017
+ .getFieldTarget()
1018
+ .handleCustomEvent(
1019
+ importOption.onSuccessImport,
1020
+ ["resultData", "file"],
1021
+ [resultData, file]
1022
+ );
1023
+ };
1024
+ const close = () => {
1025
+ that.dialogClose1();
1026
+ }
1027
+ try {
1028
+ if (importOption.onConfirmImportEnabled) {
1029
+ if (
1030
+ that
1031
+ .getFieldTarget()
1032
+ .handleCustomEvent(
1033
+ importOption.onConfirmImport,
1034
+ ["resultData", "file", "done", 'close'],
1035
+ [resultData, file, done, close]
1036
+ ) !== false
1037
+ ) {
1038
+ done();
1039
+ }
1040
+ } else if (importOption.tableRef) {
1041
+ let tableRef = that
1042
+ .getFieldTarget()
1043
+ .getWidgetRef(importOption.tableRef);
1044
+ tableRef && tableRef.addTableData(resultData.data);
1045
+ done();
1046
+ }
1047
+ } catch (et) {
1048
+ console.error(et);
1049
+ }
1050
+ setTimeout(function () {
1051
+ that.loadingObj && that.loadingObj.close();
1052
+ }, 200);
1053
+ });
1054
+ },
1055
+
1056
+ //begin
1057
+ fileParse(file, type = "base64", callback) {
1058
+ let fileRead = new FileReader();
1059
+ if (type === "base64") {
1060
+ fileRead.readAsDataURL(file);
1061
+ } else if (type === "buffer") {
1062
+ fileRead.readAsArrayBuffer(file);
1063
+ }
1064
+ fileRead.onload = (ev) => {
1065
+ callback(ev.target.result);
1066
+ };
1067
+ },
1068
+ getUploadText(percent) {
1069
+ return this.$t1("上传导入文件 {percent}%", { percent });
1070
+ },
1071
+ changeUploadPercent(percent) {
1072
+ // return this.$t1('上传导入文件 {percent}%', {percent})
1073
+ this.percent1 = percent;
1074
+ this.loadingIndex = 1;
1075
+ },
1076
+ uploadFile(callback) {
1077
+ let that = this;
1078
+ that.loadingPercent = 0;
1079
+ // that.loadingTitle = this.getUploadText(0);
1080
+ that.changeUploadPercent(0);
1081
+ let file = this.fileRaw;
1082
+ let uploadChunkSize = 5;
1083
+ this.importLoading = true;
1084
+ this.fileUploadCallback = callback;
1085
+ this.fileParse(file, "buffer", (buffer) => {
1086
+ let spark = new SparkMD5.ArrayBuffer(),
1087
+ chunkSize = uploadChunkSize * 1024 * 1024, // Read in chunks of 2MB
1088
+ chunks = Math.ceil(file.size / chunkSize),
1089
+ hash,
1090
+ suffix;
1091
+ spark.append(buffer);
1092
+ hash = spark.end();
1093
+ let md5 = hash;
1094
+ let nameSplit = /\.([0-9a-zA-Z]+)$/i.exec(file.name);
1095
+
1096
+ suffix = nameSplit && nameSplit.length > 1 ? nameSplit[1] : "";
1097
+
1098
+ let chunkParam = {
1099
+ fullFile: file,
1100
+ chunkSize: chunkSize,
1101
+ chunks: chunks,
1102
+ chunkIndex: 0,
1103
+ md5: hash,
1104
+ uuid: "",
1105
+ name: file.name,
1106
+ };
1107
+ file.chunkParam = chunkParam;
1108
+
1109
+ this.sendRequest(file);
1110
+ });
1111
+ },
1112
+ async sendRequest(fullFile) {
1113
+ if (!this.showImportDialog2) return;
1114
+ let that = this;
1115
+ let uploadUrl = USER_PREFIX + "/excel_import/uploadFile";
1116
+ let chunkParam = fullFile.chunkParam;
1117
+ let target = that.$refs.upload;
1118
+ let abort;
1119
+ let config = {
1120
+ headers: {
1121
+ "Content-Type": "multipart/form-data",
1122
+ },
1123
+ cancelToken: new axios.CancelToken(function executor(c) {
1124
+ abort = c;
1125
+ fullFile.abort = c;
1126
+ }),
1127
+ onUploadProgress: (progressEvent) => {
1128
+ let start = chunkParam.start;
1129
+ let uploadedSize =
1130
+ start +
1131
+ Math.floor(
1132
+ (chunkParam.currentSize * progressEvent.loaded) /
1133
+ progressEvent.total
1134
+ );
1135
+ let percent = Math.floor((uploadedSize * 100) / fullFile.size);
1136
+ if (percent === 100) {
1137
+ percent = 99;
1138
+ }
1139
+ that.loadingPercent = percent;
1140
+
1141
+ // that.$set(that, 'loadingTitle', this.getUploadText(percent))
1142
+ that.changeUploadPercent(percent);
1143
+ },
1144
+ // failMsg: false,
1145
+ modal: false,
1146
+ callback: (res1) => {
1147
+ if (res1.type === "success") {
1148
+ let uuid = res1.objx.uuid;
1149
+ chunkParam.uuid = uuid;
1150
+ if (preFormData.chunk + 1 >= preFormData.chunks) {
1151
+ let mergeData = {
1152
+ name: chunkParam.name,
1153
+ md5: chunkParam.md5,
1154
+ uuid: uuid,
1155
+ };
1156
+ let _param = {
1157
+ mergeData: mergeData,
1158
+ chunkParam: chunkParam,
1159
+ };
1160
+ setTimeout(() => {
1161
+ this.mergeFile(_param);
1162
+ }, 100);
1163
+ } else {
1164
+ chunkParam.chunkIndex = chunkParam.chunkIndex + 1;
1165
+ chunkParam.uuid = uuid;
1166
+ setTimeout(() => {
1167
+ this.sendRequest(fullFile);
1168
+ }, 100);
1169
+ }
1170
+ } else {
1171
+ this.dialogClose2(0);
1172
+ }
1173
+ return res1;
1174
+ },
1175
+ error: (err) => {
1176
+ console.log(err);
1177
+ this.dialogClose2(0);
1178
+ },
1179
+ }; //添加请求头
1180
+
1181
+ let chunkIndex = chunkParam.chunkIndex;
1182
+ let chunkSize = chunkParam.chunkSize;
1183
+ let start = chunkIndex * chunkSize,
1184
+ end =
1185
+ start + chunkSize >= fullFile.size
1186
+ ? fullFile.size
1187
+ : start + chunkParam.chunkSize;
1188
+ chunkParam.currentSize = end - start;
1189
+ chunkParam.start = start;
1190
+ chunkParam.end = end;
1191
+
1192
+ let preFormData = {
1193
+ file: fullFile.slice(start, end),
1194
+ name: fullFile.name,
1195
+ chunks: chunkParam.chunks,
1196
+ chunk: chunkIndex,
1197
+ md5: chunkParam.md5,
1198
+ uuid: chunkParam.uuid,
1199
+ };
1200
+
1201
+ let formData = new FormData();
1202
+ Object.keys(preFormData).forEach((key) => {
1203
+ formData.append(key, preFormData[key]);
1204
+ });
1205
+
1206
+ let req = this.$http.post(uploadUrl, formData, config);
1207
+ req.abort = () => {
1208
+ abort(this.$t2("取消上传", "components.VabUpload.cancelUpload"));
1209
+ };
1210
+ },
1211
+ mergeFile(param) {
1212
+ if (!this.showImportDialog2) return;
1213
+ let that = this;
1214
+ let mergeData = param.mergeData;
1215
+ let chunkParam = param.chunkParam;
1216
+ let fullFile = chunkParam.fullFile;
1217
+ let mergeUrl = USER_PREFIX + "/excel_import/mergeChunk";
1218
+ let target = this.$refs.upload;
1219
+ this.$http({
1220
+ url: mergeUrl,
1221
+ method: "post",
1222
+ data: mergeData,
1223
+ // failMsg: false,
1224
+ modal: false,
1225
+ cancelToken: new axios.CancelToken(function executor(c) {
1226
+ if (fullFile) fullFile.abort = c;
1227
+ }),
1228
+ callback: (res) => {
1229
+ if (res.type === "success") {
1230
+ that.loadingPercent = 100;
1231
+ // that.loadingTitle = this.getUploadText(100);
1232
+ this.changeUploadPercent(100);
1233
+ setTimeout(() => {
1234
+ this.checkImportData();
1235
+ }, 100);
1236
+ } else {
1237
+ this.dialogClose2(0);
1238
+ }
1239
+ },
1240
+ error: (e) => {
1241
+ console.log(err);
1242
+ this.dialogClose2(0);
1243
+ },
1244
+ });
1245
+ },
1246
+ getCheckText(percent) {
1247
+ return this.$t1("校验导入文件中的图片数据格式 {percent}%", { percent });
1248
+ },
1249
+ changeCheckTextPercent(percent) {
1250
+ this.percent2 = percent;
1251
+ this.loadingIndex = 2;
1252
+ },
1253
+ checkImportData() {
1254
+ if (!this.showImportDialog2) return;
1255
+ let that = this;
1256
+ that.loadingPercent = 0;
1257
+ // that.loadingTitle = this.getCheckText(0);
1258
+ that.changeCheckTextPercent(0);
1259
+ let fullFile = this.fileRaw;
1260
+ let chunkParam = fullFile.chunkParam;
1261
+
1262
+ this.$http({
1263
+ url: USER_PREFIX + "/excel_import/checkData",
1264
+ method: "post",
1265
+ data: {
1266
+ name: chunkParam.name,
1267
+ md5: chunkParam.md5,
1268
+ uuid: chunkParam.uuid,
1269
+ },
1270
+ // failMsg: false,
1271
+ modal: false,
1272
+ cancelToken: new axios.CancelToken(function executor(c) {
1273
+ if (fullFile) fullFile.abort = c;
1274
+ }),
1275
+ onUploadProgress: (progressEvent) => {
1276
+ let percent = Math.floor(
1277
+ (progressEvent.loaded * 100) / progressEvent.total
1278
+ );
1279
+ if (percent === 100) {
1280
+ percent = 99;
1281
+ }
1282
+ that.loadingPercent = percent;
1283
+ // that.$set(that, 'loadingTitle', this.getCheckText(percent))
1284
+ that.changeCheckTextPercent(percent);
1285
+ },
1286
+ callback: (res) => {
1287
+ if (res.type === "success") {
1288
+ that.loadingPercent = 100;
1289
+ // that.loadingTitle = this.getCheckText(100);
1290
+ that.changeCheckTextPercent(100);
1291
+ this.handleImageData();
1292
+ } else {
1293
+ this.dialogClose2(0);
1294
+ }
1295
+ },
1296
+ error: (e) => {
1297
+ console.log(err);
1298
+ this.dialogClose2(0);
1299
+ },
1300
+ });
1301
+ },
1302
+ getSaveImageText(percent) {
1303
+ return this.$t1("存储导入文件中的图片 {percent}%", { percent });
1304
+ },
1305
+ changeSaveImageTextPercent(percent) {
1306
+ // return this.$t1('存储导入文件中的图片 {percent}%', {percent})
1307
+ this.percent3 = percent;
1308
+ this.loadingIndex = 3;
1309
+ },
1310
+ handleImageData() {
1311
+ let that = this;
1312
+ that.loadingPercent = 0;
1313
+ // that.loadingTitle = this.getSaveImageText(0);
1314
+ that.changeSaveImageTextPercent(0);
1315
+ this.getImportData(0);
1316
+ },
1317
+ getImportData(index) {
1318
+ if (!this.showImportDialog2) return;
1319
+ let that = this;
1320
+ let rowSize = this.handleRowSize;
1321
+ let fullFile = this.fileRaw;
1322
+ let chunkParam = fullFile.chunkParam;
1323
+ let rowDatas = this.resultData.data;
1324
+ let size = rowDatas.length;
1325
+ let currentLineNo = index + 1;
1326
+ let rowNumber = index + 3;
1327
+ let startRow = index + 3;
1328
+ let endRow = index + 3 + rowSize - 1;
1329
+ this.$http({
1330
+ url: USER_PREFIX + "/excel_import/getData",
1331
+ method: "post",
1332
+ data: {
1333
+ name: chunkParam.name,
1334
+ md5: chunkParam.md5,
1335
+ uuid: chunkParam.uuid,
1336
+ startRow: startRow,
1337
+ endRow: endRow,
1338
+ },
1339
+ // failMsg: false,
1340
+ modal: false,
1341
+ cancelToken: new axios.CancelToken(function executor(c) {
1342
+ if (fullFile) fullFile.abort = c;
1343
+ }),
1344
+ callback: (res) => {
1345
+ if (res.type === "success") {
1346
+ let rows = res?.objx?.datas || [];
1347
+ let fileCellFields = this.fileCellFields;
1348
+ rows.forEach((row) => {
1349
+ let rowIndex = row.row - 3;
1350
+ let item = rowDatas[rowIndex];
1351
+ Object.keys(row).forEach((key) => {
1352
+ if (fileCellFields.includes(key)) {
1353
+ let value = row[key] || [];
1354
+ if (!Array.isArray(value)) {
1355
+ value = [value];
1356
+ }
1357
+ item[key] = value;
1358
+ }
1359
+ });
1360
+ });
1361
+ let cIndex = index + rowSize - 1;
1362
+ let percent = Math.floor(((cIndex + 1) * 100) / size);
1363
+ that.loadingPercent = percent;
1364
+ // that.loadingTitle = this.getSaveImageText(percent);
1365
+ that.changeSaveImageTextPercent(percent);
1366
+ if (cIndex + 1 < size) {
1367
+ this.getImportData(cIndex + 1);
1368
+ } else {
1369
+ this.fileUploadCallback();
1370
+ }
1371
+ } else {
1372
+ this.dialogClose2(0);
1373
+ }
1374
+ },
1375
+ error: (e) => {
1376
+ this.dialogClose2(0);
1377
+ },
1378
+ });
1379
+ },
1380
+ async generateNewExcel() {
1381
+ let file = this.fileRaw;
1382
+ try {
1383
+ // 1. 读取原始文件
1384
+ const workbook = XLSX.read(file, { type: "binary" });
1385
+ const sheetName = workbook.SheetNames[0];
1386
+ const rawData = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
1387
+
1388
+ // 2. 提取表头和数据
1389
+ const headers = rawData.slice(0, this.headerRows);
1390
+ const bodyData = rawData.slice(this.headerRows);
1391
+
1392
+ let exporLineNos = [];
1393
+ if (this.resultType) {
1394
+ exporLineNos = this.successRows.map((item) => item.impNumber - 1);
1395
+ } else {
1396
+ exporLineNos = this.failRows.map((item) => item.impNumber - 1);
1397
+ }
1398
+ // 3. 应用筛选规则
1399
+ let selectRule = (row, index) => {
1400
+ return exporLineNos.includes(index);
1401
+ };
1402
+ const filteredData = bodyData.filter(
1403
+ (row, index) => {
1404
+ return selectRule(row, index + this.headerRows);
1405
+ }
1406
+ // this.selectRule(row, index + this.headerRows) // 注意索引转换
1407
+ );
1408
+
1409
+ // 4. 合并数据
1410
+ const newData = [...headers, ...filteredData];
1411
+
1412
+ // 5. 生成新文件
1413
+ const newWorkbook = XLSX.utils.book_new();
1414
+ const newSheet = XLSX.utils.aoa_to_sheet(newData);
1415
+ XLSX.utils.book_append_sheet(newWorkbook, newSheet, "Sheet1");
1416
+
1417
+ // 6. 下载文件
1418
+ const blob = XLSX.write(newWorkbook, {
1419
+ bookType: "xlsx",
1420
+ type: "array",
1421
+ });
1422
+
1423
+ const url = URL.createObjectURL(blob);
1424
+ const a = document.createElement("a");
1425
+ a.href = url;
1426
+ let fileName = null;
1427
+ if (this.resultType) {
1428
+ fileName = `导入结果(成功).xlsx`;
1429
+ } else {
1430
+ fileName = `导入结果(失败).xlsx`;
1431
+ }
1432
+ a.download = fileName;
1433
+ a.click();
1434
+
1435
+ // 7. 更新进度
1436
+ this.progress = 100;
1437
+ setTimeout(() => (this.progress = 0), 1000);
1438
+ } catch (error) {
1439
+ console.error("处理文件时出错:", error);
1440
+ }
1441
+ },
1442
+ //end
1443
+ getLoadingClass(flag, percent) {
1444
+ let classStr = null;
1445
+ let loadingIndex = this.loadingIndex;
1446
+ if (percent >= 100) {
1447
+ classStr = "ok";
1448
+ } else if (flag === loadingIndex) {
1449
+ classStr = "loading";
1450
+ }
1451
+ return classStr;
1452
+ },
1453
+
1454
+ /***sheet1 */
1455
+ async readExcel2(file, callback) {
1456
+ let that = this;
1457
+ let option = this.option;
1458
+
1459
+ const fileReader = new FileReader();
1460
+ fileReader.onload = async (ev) => {
1461
+ let resultData;
1462
+ try {
1463
+ const data = ev.target.result;
1464
+ const workbook = configUtil.XLSX.read(data, {
1465
+ type: "binary",
1466
+ });
1467
+
1468
+ let sheetDatas = [];
1469
+ for (let pi = 0; pi < workbook.SheetNames.length; pi++) {
1470
+ let sheetName = workbook.SheetNames[pi];
1471
+ let sheet = workbook.Sheets[sheetName];
1472
+
1473
+ if (sheet["!ref"] === undefined || sheet["!ref"] === null) {
1474
+ that.$baseAlert(
1475
+ this.$t2(
1476
+ "请使用正确的导入模版!",
1477
+ "components.excelImport.warmMsg2"
1478
+ )
1479
+ );
1480
+ that.handleClose2();
1481
+ return false;
1482
+ }
1483
+ let range = configUtil.XLSX.utils.decode_range(sheet["!ref"]);
1484
+ let dataSize = range.e.r + 1; //行数
1485
+ that.dataSize = dataSize - 3 >= 0 ? dataSize - 3 : 0;
1486
+ let titles = [];
1487
+ let fields = [];
1488
+
1489
+ const ws = workbook.Sheets[sheet];
1490
+
1491
+ let prefix = option.prefix;
1492
+ let excelUrl = option.excel;
1493
+
1494
+ let excelRows = [];
1495
+ let row;
1496
+ let rowNum;
1497
+ let colNum;
1498
+ for (rowNum = range.s.r; rowNum <= range.e.r; rowNum++) {
1499
+ row = [];
1500
+ for (colNum = range.s.c; colNum <= range.e.c; colNum++) {
1501
+ let nextCell =
1502
+ sheet[
1503
+ configUtil.XLSX.utils.encode_cell({
1504
+ r: rowNum,
1505
+ c: colNum,
1506
+ })
1507
+ ];
1508
+ if (typeof nextCell === "undefined") {
1509
+ row.push(void 0);
1510
+ } else {
1511
+ row.push(nextCell.w.trim());
1512
+ }
1513
+ }
1514
+ if (rowNum === 1) {
1515
+ titles = row;
1516
+ }
1517
+ if (rowNum === 2) {
1518
+ fields = row;
1519
+ let checkResult = true;
1520
+ }
1521
+ if (rowNum > 2) {
1522
+ let item = {};
1523
+ for (let i = 0; i < fields.length; i++) {
1524
+ let field = fields[i];
1525
+ if (field) {
1526
+ item[field] = row[i] ?? null;
1527
+ }
1528
+ }
1529
+ excelRows.push(item);
1530
+ }
1531
+ }
1532
+ if (
1533
+ !titles.length ||
1534
+ !fields.length ||
1535
+ titles.length !== fields.length
1536
+ ) {
1537
+ that.$baseAlert(
1538
+ this.$t2(
1539
+ "请使用正确的导入模版!",
1540
+ "components.excelImport.warmMsg2"
1541
+ )
1542
+ );
1543
+ // that.handleClose2();
1544
+ return false;
1545
+ }
1546
+
1547
+ let columns = [];
1548
+ let cols = [];
1549
+ let uniqueFields = [];
1550
+ let uniqueKeys = [];
1551
+ for (let i = 0; i < titles.length; i++) {
1552
+ let title = titles[i];
1553
+ if (title) {
1554
+ let field = fields[i];
1555
+ if (field === null || field === undefined) {
1556
+ that.$baseAlert(
1557
+ this.$t2(
1558
+ "请使用正确的导入模版!",
1559
+ "components.excelImport.warmMsg2"
1560
+ )
1561
+ );
1562
+ // that.handleClose2();
1563
+ return false;
1564
+ }
1565
+ let t = title.substr(-1);
1566
+ let u = title.length >= 2 ? title.substr(-2) : title;
1567
+ let p = title.length >= 3 ? title.substr(-3) : title;
1568
+ let isNeed = false;
1569
+ if (t === "*") {
1570
+ isNeed = true;
1571
+ }
1572
+ let isUnique = false;
1573
+ /* if (u === "**") {
1574
+ uniqueFields.push(field);
1575
+ isUnique = true;
1576
+ } */
1577
+ let isSheetUnique = false;
1578
+ if (p === "***") {
1579
+ uniqueKeys.push(field);
1580
+ isSheetUnique = true;
1581
+ }
1582
+ if (!uniqueKeys.length) {
1583
+ // that.clearImportTimer();
1584
+ that.$baseAlert(
1585
+ `[${sheetName}]` + that.$t1("缺失单据唯一标识***")
1586
+ );
1587
+ // that.handleClose2();
1588
+ return false;
1589
+ }
1590
+
1591
+ let otherConfig = {};
1592
+ let isFile = false;
1593
+ if (field.startsWith("attachments_")) {
1594
+ that.fileCellFields.push(field);
1595
+ isFile = true;
1596
+ otherConfig = {
1597
+ slots: {
1598
+ default: "attachment",
1599
+ },
1600
+ };
1601
+ }
1602
+
1603
+ let col = {
1604
+ field: field,
1605
+ title: title,
1606
+ width: 100,
1607
+ isNeed: isNeed,
1608
+ isUnique: isUnique,
1609
+ isFile,
1610
+ otherConfig,
1611
+ isSheetUnique,
1612
+ };
1613
+ cols.push(col);
1614
+ }
1615
+ }
1616
+
1617
+ let oriCols = JSON.parse(JSON.stringify(cols)); //列信息
1618
+ /* if (uniqueKeys.length) {
1619
+ //分组唯一字段为空时,全部不发包。
1620
+ for (let i = 0; i < oriCols.length; i++) {
1621
+ let oriCol = oriCols[i];
1622
+ if (uniqueKeys.includes(oriCol.field)) {
1623
+ for (let j = 0; j < excelRows.length; j++) {
1624
+ let data = excelRows[j];
1625
+ let value = data[oriCol.field];
1626
+ if (value === null || value === undefined || value === "") {
1627
+ that.errorHandle(`[${sheetName}]`+
1628
+ that.$t2(
1629
+ "第" + (j + 4) + "行[" + oriCol.title + "]不能为空;",
1630
+ "components.excelImport.warmMsg3",
1631
+ {
1632
+ lineNo: j + 4,
1633
+ title: oriCol.title,
1634
+ }
1635
+ ));
1636
+ return false;
1637
+ }
1638
+ }
1639
+ }
1640
+ }
1641
+ } */
1642
+ // this.oriCols = oriCols;
1643
+
1644
+ let resultData1 = {
1645
+ sheetName: sheetName,
1646
+ data: excelRows,
1647
+ titles: titles,
1648
+ fields: fields,
1649
+ uniqueFields: uniqueFields,
1650
+ oriCols: oriCols,
1651
+ uniqueKeys,
1652
+ };
1653
+ sheetDatas.push(resultData1);
1654
+ }
1655
+
1656
+ //校验必填
1657
+ if (!that.checkAllSheetData(sheetDatas)) {
1658
+ return false;
1659
+ }
1660
+
1661
+ //合并多sheet数据
1662
+ let newDatas = [];
1663
+ resultData = that.$baseLodash.cloneDeep(sheetDatas[0]);
1664
+ let uniqueKey = resultData.uniqueKeys[0];
1665
+ let data2 = [];
1666
+ for (let i = 0; i < resultData.data.length; i++) {
1667
+ let item = resultData.data[i];
1668
+ let sheetName = resultData[sheetName];
1669
+ let uniqueValue = item[uniqueKey];
1670
+
1671
+ if (!that.isNull(uniqueValue)) {
1672
+ let newItem = { ...item };
1673
+ let allItems = [];
1674
+ for (let j = 1; j < sheetDatas.length; j++) {
1675
+ let sheetData = sheetDatas[j];
1676
+ let fDatas = [];
1677
+ for (let k = 0; k < sheetData.data.length; k++) {
1678
+ let sheetItem = sheetData.data[k];
1679
+ if (that.isNull(sheetItem[uniqueKey])) {
1680
+ that.handleCellNotNull(k, sheetData);
1681
+ return;
1682
+ }
1683
+ if (sheetItem[uniqueKey] === uniqueValue) {
1684
+ fDatas.push(sheetItem);
1685
+ }
1686
+ }
1687
+ allItems.push(fDatas);
1688
+ }
1689
+ newItem.sheetItems = allItems;
1690
+ data2.push(newItem);
1691
+ } else {
1692
+ that.handleCellNotNull(i, resultData);
1693
+ return false;
1694
+ }
1695
+ }
1696
+
1697
+ resultData.sheetDatas = sheetDatas;
1698
+ resultData.data = data2;
1699
+ this.oriCols = resultData.oriCols;
1700
+ this.resultData = resultData;
1701
+ callback(resultData);
1702
+ } catch (et) {
1703
+ that.showContent = false;
1704
+ that.clearImportTimer();
1705
+ console.error(et);
1706
+ }
1707
+ };
1708
+ fileReader.readAsBinaryString(file);
1709
+ },
1710
+ isNull(val) {
1711
+ if (val === null || val === undefined || val === "" || val === undefined || val === null) {
1712
+ return true;
1713
+ }
1714
+ },
1715
+ checkAllSheetData(sheetItems){
1716
+ let that = this;
1717
+ for(let sheetItem of sheetItems){
1718
+ let oriCols = sheetItem.oriCols;
1719
+ let uniqueKeys = sheetItem.uniqueKeys;
1720
+ let excelRows = sheetItem.data;
1721
+ let sheetName = sheetItem.sheetName;
1722
+
1723
+ for (let i = 0; i < oriCols.length; i++) {
1724
+ let oriCol = oriCols[i];
1725
+ if (oriCol.isNeed || uniqueKeys.includes(oriCol.field)) {
1726
+ for (let j = 0; j < excelRows.length; j++) {
1727
+ let data = excelRows[j];
1728
+ let value = data[oriCol.field];
1729
+ if (that.isNull(value)) {
1730
+ that.errorHandle(`[${sheetName}]`+
1731
+ that.$t2(
1732
+ "第" + (j + 4) + "行[" + oriCol.title + "]不能为空;",
1733
+ "components.excelImport.warmMsg3",
1734
+ {
1735
+ lineNo: j + 4,
1736
+ title: oriCol.title,
1737
+ }
1738
+ ));
1739
+ return false;
1740
+ }
1741
+ }
1742
+ }
1743
+ }
1744
+
1745
+ }
1746
+ return true;
1747
+ },
1748
+
1749
+
1750
+ handleCellNotNull(i, sheetData) {
1751
+ let that = this;
1752
+ let uniqueKey = sheetData.uniqueKeys[0];
1753
+ let oriCol = sheetData.oriCols.find((item) => item.field === uniqueKey);
1754
+ that.errorHandle(
1755
+ `[${sheetData.sheetName}]` +
1756
+ that.$t2(
1757
+ "第" + (i + 4) + "行[" + oriCol.title + "]不能为空;",
1758
+ "components.excelImport.warmMsg3",
1759
+ {
1760
+ lineNo: i + 4,
1761
+ title: oriCol.title,
1762
+ }
1763
+ )
1764
+ );
1765
+ },
1766
+ errorHandle(errorText) {
1767
+ this.clearImportTimer();
1768
+ this.$baseAlert(errorText);
1769
+ // this.handleClose2();
1770
+ },
1771
+ /***sheet2 */
1772
+ },
1773
+ };
1774
+ export const mixins = tmixins;