cloud-web-corejs 1.0.54-dev.8 → 1.0.54-dev.800

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 (804) hide show
  1. package/package.json +203 -177
  2. package/src/App.vue +73 -75
  3. package/src/api/user.js +85 -40
  4. package/src/components/Qrcode/fileParse.vue +0 -1
  5. package/src/components/Tinymce/index.vue +112 -71
  6. package/src/components/VabUpload/fileLibraryDialog.vue +296 -0
  7. package/src/components/VabUpload/image-viewer.vue +2 -2
  8. package/src/components/VabUpload/index.js +69 -1
  9. package/src/components/VabUpload/index.vue +242 -230
  10. package/src/components/VabUpload/mixins/fileLibraryDialog.js +1112 -0
  11. package/src/components/VabUpload/mixins.js +1971 -9
  12. package/src/components/VabUpload/privateProfileDialog.vue +2 -2
  13. package/src/components/VabUpload/propertiesDialog.vue +1 -1
  14. package/src/components/VabUpload/view.vue +209 -119
  15. package/src/components/advancedSearchDialog/mixins.js +28 -1
  16. package/src/components/base-textarea/index.vue +104 -0
  17. package/src/components/baseAlert/index.js +44 -1
  18. package/src/components/baseAlert/index.vue +24 -20
  19. package/src/components/baseAlert/mixins.js +61 -1
  20. package/src/components/baseArea/index.vue +1628 -0
  21. package/src/components/baseAttachment/index.vue +49 -40
  22. package/src/components/baseAttachment/install.js +21 -5
  23. package/src/components/baseAttachment/mixins.js +310 -1
  24. package/src/components/baseInputBatch/mixins.js +58 -1
  25. package/src/components/baseInputExport/index.vue +21 -14
  26. package/src/components/baseInputExport/mixins.js +415 -8
  27. package/src/components/baseInputNumber/index.vue +9 -9
  28. package/src/components/baseTabs/index.vue +16 -8
  29. package/src/components/baseTabs/mixins.js +176 -1
  30. package/src/components/bizTab/BizBillActions.vue +129 -0
  31. package/src/components/bizTab/BizTabListPage.vue +391 -0
  32. package/src/components/bizTab/README.md +378 -0
  33. package/src/components/bizTab/billTableUtil.js +48 -0
  34. package/src/components/bizTab/billValidators.js +136 -0
  35. package/src/components/bizTab/bizBillDetailMixin.js +687 -0
  36. package/src/components/bizTab/index.js +24 -0
  37. package/src/components/cnPrint/index.js +44 -1
  38. package/src/components/cnPrint/mixins.js +189 -1
  39. package/src/components/code-editor/async.js +29 -0
  40. package/src/components/code-editor/index.vue +190 -62
  41. package/src/components/confirmDialog/index.js +41 -1
  42. package/src/components/confirmDialog/index.vue +24 -17
  43. package/src/components/confirmDialog/mixins.js +31 -1
  44. package/src/components/errorMsg/index.js +47 -3
  45. package/src/components/errorMsg/index.vue +78 -70
  46. package/src/components/errorMsg/mixins.js +103 -5
  47. package/src/components/excelExport/button.vue +86 -24
  48. package/src/components/excelExport/exportFieldDialog.vue +373 -113
  49. package/src/components/excelExport/exportType.js +49 -0
  50. package/src/components/excelExport/index.js +43 -9
  51. package/src/components/excelExport/index.vue +113 -28
  52. package/src/components/excelExport/mixins.js +1153 -722
  53. package/src/components/excelImport/index.js +75 -13
  54. package/src/components/excelImport/index.vue +2 -1
  55. package/src/components/excelImport/mixins.js +841 -8
  56. package/src/components/fileLibrary/categoryMoveDialog.vue +109 -109
  57. package/src/components/fileLibrary/fileHistoryDialog.vue +1 -1
  58. package/src/components/fileLibrary/fileObjAuthDialog.vue +297 -186
  59. package/src/components/fileLibrary/fileObjAuthEdit.vue +1 -1
  60. package/src/components/fileLibrary/fileObjAuthEditDialog.vue +7 -1
  61. package/src/components/fileLibrary/fileObjNotifyEdit.vue +192 -0
  62. package/src/components/fileLibrary/filterDialog.vue +454 -0
  63. package/src/components/fileLibrary/index.vue +1109 -687
  64. package/src/components/fileLibrary/mixins/categoryMoveDialogMixins.js +1 -1
  65. package/src/components/fileLibrary/mixins/fileCategoryDialogMixins.js +1 -1
  66. package/src/components/fileLibrary/mixins/fileHistoryDialogMixins.js +2 -2
  67. package/src/components/fileLibrary/mixins/fileObjAuthDialogMixin.js +341 -207
  68. package/src/components/fileLibrary/mixins/fileObjAuthEditDialogMixin.js +33 -26
  69. package/src/components/fileLibrary/mixins/fileObjAuthEditMixin.js +5 -5
  70. package/src/components/fileLibrary/mixins/indexMixins.js +255 -112
  71. package/src/components/fileLibrary/mixins/propertiesDialogMixins.js +64 -4
  72. package/src/components/fileLibrary/mixins/recycleBinDialogMixins.js +3 -3
  73. package/src/components/fileLibrary/propertiesDialog.vue +190 -145
  74. package/src/components/fileLibrary/recycleBinDialog.vue +237 -236
  75. package/src/components/fileLibrary/shareDialog.vue +1 -1
  76. package/src/components/formDialog/README.md +371 -0
  77. package/src/components/formDialog/actionButtons.js +90 -0
  78. package/src/components/formDialog/index.js +48 -0
  79. package/src/components/formDialog/index.vue +802 -0
  80. package/src/components/formDrawer/drawer.vue +722 -0
  81. package/src/components/formDrawer/index.js +50 -0
  82. package/src/components/formOplog/mixins.js +85 -4
  83. package/src/components/hiprint/css/bootstrap.min.css +6 -0
  84. package/src/components/hiprint/fonts/glyphicons-halflings-regular.eot +0 -0
  85. package/src/components/hiprint/fonts/glyphicons-halflings-regular.svg +288 -0
  86. package/src/components/hiprint/fonts/glyphicons-halflings-regular.ttf +0 -0
  87. package/src/components/hiprint/fonts/glyphicons-halflings-regular.woff +0 -0
  88. package/src/components/hiprint/fonts/glyphicons-halflings-regular.woff2 +0 -0
  89. package/src/components/hiprint/hiprint.bundle.js +15 -3
  90. package/src/components/hiprint/view/design/index.vue +146 -48
  91. package/src/components/hiprint/view/design/mixins.js +611 -1
  92. package/src/components/hiprint/view/design/preview.vue +75 -52
  93. package/src/components/hiprint/view/json-view.vue +31 -31
  94. package/src/components/jdPrint/index.js +44 -1
  95. package/src/components/jdPrint/mixins.js +208 -1
  96. package/src/components/jsonImport/exportUtil.js +106 -0
  97. package/src/components/jsonImport/index.js +212 -17
  98. package/src/components/jsonImport/mixins.js +350 -16
  99. package/src/components/langImport/index.js +80 -1
  100. package/src/components/langImport/mixins.js +487 -1
  101. package/src/components/langTag/mixins/addButton.js +51 -5
  102. package/src/components/langTag/mixins/deleteButton.js +55 -5
  103. package/src/components/langTag/mixins/view.js +47 -5
  104. package/src/components/luckysheet/dialog.vue +159 -0
  105. package/src/components/luckysheet/export.js +595 -0
  106. package/src/components/luckysheet/fileUtils.js +147 -0
  107. package/src/components/luckysheet/index.js +72 -0
  108. package/src/components/luckysheet/templateJson.js +12078 -0
  109. package/src/components/luckysheet/view.vue +210 -0
  110. package/src/components/micro-view-host/contract.js +66 -0
  111. package/src/components/micro-view-host/index.vue +148 -0
  112. package/src/components/mobile/file/index.vue +10 -0
  113. package/src/components/mobile/wf/mixins/wfModifyDialogMixin.js +51 -47
  114. package/src/components/obsUpload/index.js +34 -0
  115. package/src/components/obsUpload/index.vue +234 -0
  116. package/src/components/obsUpload/mixins.js +1542 -0
  117. package/src/components/onlineTalk/index.vue +328 -6
  118. package/src/components/onlineTalk/mixins.js +852 -1
  119. package/src/components/onlineTalk/talkUserDialog.vue +280 -0
  120. package/src/components/oplogTable/mixins.js +83 -4
  121. package/src/components/pddPrint/index.js +44 -1
  122. package/src/components/pddPrint/mixins.js +252 -1
  123. package/src/components/projectTag/mixins/addButton.js +52 -1
  124. package/src/components/projectTag/mixins/deleteButton.js +52 -1
  125. package/src/components/projectTag/mixins/view.js +43 -1
  126. package/src/components/scriptDescription/button.vue +12 -4
  127. package/src/components/scriptDescription/mixins.js +30 -1
  128. package/src/components/scriptTest/mixins.js +90 -1
  129. package/src/components/statusTag/mixins.js +66 -1
  130. package/src/components/table/CellSlot.vue +12 -9
  131. package/src/components/table/config.js +74 -1
  132. package/src/components/table/index.js +1220 -10
  133. package/src/components/table/plugins/extend-cell-area/vxe-table-extend-cell-area.es6.min.js +11028 -0
  134. package/src/components/table/plugins/extend-cell-area/vxe-table-extend-cell-area.min.css +200 -0
  135. package/src/components/table/tableForm.vue +102 -64
  136. package/src/components/table/tableFormMixin.js +285 -1
  137. package/src/components/table/util/index.js +337 -0
  138. package/src/components/table/vxeFilter/index.js +153 -1
  139. package/src/components/table/vxeFilter/mixin.js +310 -6
  140. package/src/components/tempStorage/index.vue +76 -55
  141. package/src/components/tempStorage/tempStorageDialog.vue +179 -54
  142. package/src/components/vb-tabs/x-tabs.vue +167 -112
  143. package/src/components/vipPrint/index.js +44 -1
  144. package/src/components/vipPrint/mixins.js +268 -1
  145. package/src/components/wf/addOpinionButton.vue +57 -0
  146. package/src/components/wf/addTaskUserdialog.vue +1 -1
  147. package/src/components/wf/content.vue +834 -362
  148. package/src/components/wf/content2.vue +4 -2
  149. package/src/components/wf/mixins/addOpinionButton.js +53 -0
  150. package/src/components/wf/mixins/setCandidateButton.js +161 -0
  151. package/src/components/wf/mixins/setCandidateDialog.js +217 -5
  152. package/src/components/wf/mixins/setCandidateDialog2.js +252 -0
  153. package/src/components/wf/mixins/wfFlowEleScriptDialog.js +131 -0
  154. package/src/components/wf/mixins/wfTaskUserRangeDialog.js +69 -0
  155. package/src/components/wf/setCandidateButton.vue +40 -0
  156. package/src/components/wf/setCandidateDialog.vue +10 -0
  157. package/src/components/wf/setCandidateDialog2.vue +105 -0
  158. package/src/components/wf/wf.js +2242 -30
  159. package/src/components/wf/wfButtonName.js +60 -0
  160. package/src/components/wf/wfFlowEleScriptDialog.vue +89 -0
  161. package/src/components/wf/wfStartDialog.vue +66 -42
  162. package/src/components/wf/wfTaskUserRangeDialog.vue +65 -0
  163. package/src/components/wf/wfUtil.js +327 -13
  164. 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
  165. 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
  166. 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
  167. package/src/components/xform/docs/2026-08 /345/210/227/350/241/250/345/257/274/345/207/272/350/204/261/346/225/217/345/210/227/345/211/224/351/231/244/350/220/275/345/234/260/346/226/207/346/241/243.md" +173 -0
  168. 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
  169. package/src/components/xform/docs//345/220/216/345/217/260/345/255/227/346/256/265/357/274/210/345/212/250/346/200/201/347/224/237/346/210/220/357/274/211JSON /350/257/264/346/230/216.md" +1286 -0
  170. 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
  171. 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
  172. 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
  173. package/src/components/xform/form-designer/designer.js +2080 -29
  174. package/src/components/xform/form-designer/form-widget/components/gantt/index.vue +434 -0
  175. package/src/components/xform/form-designer/form-widget/container-widget/containerMixin.js +108 -1
  176. package/src/components/xform/form-designer/form-widget/container-widget/data-table-mixin.js +291 -8
  177. package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +15 -2
  178. package/src/components/xform/form-designer/form-widget/container-widget/detail-pane-widget.vue +3 -2
  179. package/src/components/xform/form-designer/form-widget/container-widget/detail-plain-widget.vue +76 -0
  180. package/src/components/xform/form-designer/form-widget/container-widget/detail-widget.vue +62 -8
  181. package/src/components/xform/form-designer/form-widget/dialog/baseFormulaDialog copy.vue +971 -0
  182. package/src/components/xform/form-designer/form-widget/dialog/baseFormulaDialog.vue +971 -0
  183. package/src/components/xform/form-designer/form-widget/dialog/exportDialog.vue +13 -0
  184. package/src/components/xform/form-designer/form-widget/dialog/fileReferenceDialog.vue +320 -0
  185. package/src/components/xform/form-designer/form-widget/dialog/formDialog.vue +209 -50
  186. package/src/components/xform/form-designer/form-widget/dialog/formFieldDialog.vue +3 -3
  187. package/src/components/xform/form-designer/form-widget/dialog/formulaDialog.vue +799 -0
  188. package/src/components/xform/form-designer/form-widget/dialog/importDialog.vue +38 -7
  189. package/src/components/xform/form-designer/form-widget/dialog/importDialogMixin.js +1774 -17
  190. package/src/components/xform/form-designer/form-widget/dialog/preformDialog.vue +2 -2
  191. package/src/components/xform/form-designer/form-widget/dialog/searchFormDialog.vue +224 -77
  192. package/src/components/xform/form-designer/form-widget/dialog/vabSearchDialog.vue +3 -3
  193. package/src/components/xform/form-designer/form-widget/field-widget/a-link-widget.vue +67 -54
  194. package/src/components/xform/form-designer/form-widget/field-widget/a-text-widget.vue +1 -1
  195. package/src/components/xform/form-designer/form-widget/field-widget/area-select-widget.vue +272 -0
  196. package/src/components/xform/form-designer/form-widget/field-widget/autocomplete-widget.vue +119 -0
  197. package/src/components/xform/form-designer/form-widget/field-widget/baseAttachment-widget.vue +273 -180
  198. package/src/components/xform/form-designer/form-widget/field-widget/button-widget.vue +76 -66
  199. package/src/components/xform/form-designer/form-widget/field-widget/cascader-widget.vue +209 -90
  200. package/src/components/xform/form-designer/form-widget/field-widget/census-widget.vue +41 -35
  201. package/src/components/xform/form-designer/form-widget/field-widget/checkbox-widget.vue +18 -7
  202. package/src/components/xform/form-designer/form-widget/field-widget/color-widget.vue +4 -1
  203. package/src/components/xform/form-designer/form-widget/field-widget/copy_button-widget.vue +104 -0
  204. package/src/components/xform/form-designer/form-widget/field-widget/date-range-widget.vue +15 -3
  205. package/src/components/xform/form-designer/form-widget/field-widget/date-widget.vue +70 -7
  206. package/src/components/xform/form-designer/form-widget/field-widget/download-button-widget.vue +133 -0
  207. package/src/components/xform/form-designer/form-widget/field-widget/dropdown-item-widget.vue +86 -0
  208. package/src/components/xform/form-designer/form-widget/field-widget/dropdown-widget.vue +170 -0
  209. package/src/components/xform/form-designer/form-widget/field-widget/echart-bar-widget.vue +1 -1
  210. package/src/components/xform/form-designer/form-widget/field-widget/echart-category-widget.vue +1 -1
  211. package/src/components/xform/form-designer/form-widget/field-widget/echart-pie-widget.vue +1 -1
  212. package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +1977 -16
  213. package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +608 -108
  214. package/src/components/xform/form-designer/form-widget/field-widget/gantt-widget.vue +964 -0
  215. package/src/components/xform/form-designer/form-widget/field-widget/html-text-widget.vue +6 -2
  216. package/src/components/xform/form-designer/form-widget/field-widget/import-button-widget.vue +22 -11
  217. package/src/components/xform/form-designer/form-widget/field-widget/import2-button-widget.vue +90 -0
  218. package/src/components/xform/form-designer/form-widget/field-widget/input-widget.vue +7 -2
  219. package/src/components/xform/form-designer/form-widget/field-widget/mixins/autocomplete-mixin.js +451 -0
  220. package/src/components/xform/form-designer/form-widget/field-widget/mixins/date-limit-mixin.js +222 -0
  221. package/src/components/xform/form-designer/form-widget/field-widget/mixins/echart-bar-mixin.js +52 -17
  222. package/src/components/xform/form-designer/form-widget/field-widget/mixins/echart-category-mixin.js +64 -97
  223. package/src/components/xform/form-designer/form-widget/field-widget/mixins/echart-pie-mixin.js +16 -9
  224. package/src/components/xform/form-designer/form-widget/field-widget/mixins/time-limit-mixin.js +92 -0
  225. package/src/components/xform/form-designer/form-widget/field-widget/mixins/utc-transform-mixin.js +75 -0
  226. package/src/components/xform/form-designer/form-widget/field-widget/mixins/vabsearch-mixin.js +192 -0
  227. package/src/components/xform/form-designer/form-widget/field-widget/multiSearch-widget.vue +53 -0
  228. package/src/components/xform/form-designer/form-widget/field-widget/number-widget.vue +119 -81
  229. package/src/components/xform/form-designer/form-widget/field-widget/oplog-widget.vue +186 -0
  230. package/src/components/xform/form-designer/form-widget/field-widget/print-button-widget.vue +55 -28
  231. package/src/components/xform/form-designer/form-widget/field-widget/print-detail-button-widget.vue +119 -0
  232. package/src/components/xform/form-designer/form-widget/field-widget/project-tag-widget.vue +156 -54
  233. package/src/components/xform/form-designer/form-widget/field-widget/radio-widget.vue +26 -6
  234. package/src/components/xform/form-designer/form-widget/field-widget/save_submit_wf_button-widget.vue +115 -0
  235. package/src/components/xform/form-designer/form-widget/field-widget/script-input-widget.vue +149 -0
  236. package/src/components/xform/form-designer/form-widget/field-widget/search_button-widget.vue +2 -2
  237. package/src/components/xform/form-designer/form-widget/field-widget/select-export-button-widget.vue +86 -0
  238. package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +120 -0
  239. package/src/components/xform/form-designer/form-widget/field-widget/select-widget.vue +24 -9
  240. package/src/components/xform/form-designer/form-widget/field-widget/singerSearch-widget.vue +53 -0
  241. package/src/components/xform/form-designer/form-widget/field-widget/singleUpload-widget.vue +145 -0
  242. package/src/components/xform/form-designer/form-widget/field-widget/static-content-wrapper.vue +16 -1
  243. package/src/components/xform/form-designer/form-widget/field-widget/static-text-widget.vue +8 -3
  244. package/src/components/xform/form-designer/form-widget/field-widget/status-widget.vue +93 -49
  245. package/src/components/xform/form-designer/form-widget/field-widget/switch-widget.vue +9 -1
  246. package/src/components/xform/form-designer/form-widget/field-widget/table-export-button-widget.vue +42 -37
  247. package/src/components/xform/form-designer/form-widget/field-widget/tempStorage-widget.vue +147 -0
  248. package/src/components/xform/form-designer/form-widget/field-widget/text-widget.vue +111 -34
  249. package/src/components/xform/form-designer/form-widget/field-widget/time-range-widget.vue +4 -3
  250. package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +45 -5
  251. package/src/components/xform/form-designer/form-widget/field-widget/vabSearch-widget.vue +3 -171
  252. package/src/components/xform/form-designer/form-widget/field-widget/vabUpload-widget.vue +338 -172
  253. package/src/components/xform/form-designer/form-widget/field-widget/vabUpload2-widget.vue +753 -0
  254. package/src/components/xform/form-designer/form-widget/field-widget/vue-page-widget.vue +231 -0
  255. package/src/components/xform/form-designer/form-widget/index.vue +6 -1
  256. package/src/components/xform/form-designer/form-widget/indexMixin.js +184 -2
  257. package/src/components/xform/form-designer/index.vue +194 -191
  258. package/src/components/xform/form-designer/indexMixin.js +856 -24
  259. package/src/components/xform/form-designer/refMixinDesign.js +27 -28
  260. package/src/components/xform/form-designer/setting-panel/action-button-config-dialog.vue +241 -0
  261. package/src/components/xform/form-designer/setting-panel/dataSource-setting.vue +397 -397
  262. package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +602 -0
  263. package/src/components/xform/form-designer/setting-panel/form-setting.vue +1772 -626
  264. package/src/components/xform/form-designer/setting-panel/index.vue +313 -305
  265. package/src/components/xform/form-designer/setting-panel/indexMixin.js +370 -12
  266. package/src/components/xform/form-designer/setting-panel/option-items-setting.vue +519 -236
  267. package/src/components/xform/form-designer/setting-panel/property-editor/a-link-editor.vue +5 -5
  268. package/src/components/xform/form-designer/setting-panel/property-editor/a-text-editor.vue +4 -4
  269. package/src/components/xform/form-designer/setting-panel/property-editor/alignType-editor.vue +1 -1
  270. package/src/components/xform/form-designer/setting-panel/property-editor/autoValueEnabled-editor.vue +38 -0
  271. package/src/components/xform/form-designer/setting-panel/property-editor/buttonIcon-editor.vue +14 -15
  272. package/src/components/xform/form-designer/setting-panel/property-editor/censusClass-editor.vue +7 -1
  273. package/src/components/xform/form-designer/setting-panel/property-editor/colorClass-editor.vue +28 -0
  274. package/src/components/xform/form-designer/setting-panel/property-editor/commonAttributeEnabled-editor.vue +41 -0
  275. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/columnRenderDialog.vue +124 -0
  276. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +737 -625
  277. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/edit-tree-button-group-config-dialog.vue +281 -0
  278. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/exportItemColumns-dialog.vue +432 -0
  279. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/onCheckboxChange-editor.vue +1 -1
  280. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/table-column-dialog.vue +1632 -579
  281. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail/detail-editor.vue +96 -74
  282. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail-pane/detail-pane-editor.vue +3 -3
  283. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail-plain/detail-plain-editor.vue +75 -0
  284. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/colHeight-editor.vue +1 -1
  285. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid/gutter-editor.vue +1 -1
  286. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-height-editor.vue +1 -1
  287. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-offset-editor.vue +2 -2
  288. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-pull-editor.vue +2 -2
  289. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-push-editor.vue +2 -2
  290. package/src/components/xform/form-designer/setting-panel/property-editor/container-grid-col/grid-col-span-editor.vue +4 -4
  291. package/src/components/xform/form-designer/setting-panel/property-editor/container-h5-card/h5-card-editor.vue +124 -124
  292. package/src/components/xform/form-designer/setting-panel/property-editor/container-list-h5/list-h5-editor.vue +34 -46
  293. package/src/components/xform/form-designer/setting-panel/property-editor/container-panel/height-editor.vue +1 -1
  294. package/src/components/xform/form-designer/setting-panel/property-editor/container-panel/width-editor.vue +1 -1
  295. package/src/components/xform/form-designer/setting-panel/property-editor/container-tab/tab-customClass-editor.vue +119 -119
  296. package/src/components/xform/form-designer/setting-panel/property-editor/container-tab/tabClass-editor.vue +45 -45
  297. package/src/components/xform/form-designer/setting-panel/property-editor/container-table/table-dynamicField-editor.vue +344 -0
  298. package/src/components/xform/form-designer/setting-panel/property-editor/container-table-cell/cellHeight-editor.vue +1 -1
  299. package/src/components/xform/form-designer/setting-panel/property-editor/container-table-cell/cellWidth-editor.vue +1 -1
  300. package/src/components/xform/form-designer/setting-panel/property-editor/container-tree/tree-customClass-editor.vue +32 -3
  301. package/src/components/xform/form-designer/setting-panel/property-editor/container-tree-pane/tree-pane-editor.vue +1 -1
  302. package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/cancelButtonLabel-editor.vue +1 -1
  303. package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/okButtonLabel-editor.vue +1 -1
  304. package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/title-editor.vue +1 -1
  305. package/src/components/xform/form-designer/setting-panel/property-editor/container-vf-dialog/width-editor.vue +1 -1
  306. package/src/components/xform/form-designer/setting-panel/property-editor/containerClass-editor.vue +1 -1
  307. package/src/components/xform/form-designer/setting-panel/property-editor/copyButton-editor.vue +36 -0
  308. package/src/components/xform/form-designer/setting-panel/property-editor/customClass-editor.vue +1 -1
  309. package/src/components/xform/form-designer/setting-panel/property-editor/defaultValue-editor.vue +1 -1
  310. package/src/components/xform/form-designer/setting-panel/property-editor/descriptionsItems-editor.vue +4 -4
  311. package/src/components/xform/form-designer/setting-panel/property-editor/downloadButtonFlag-editor.vue +32 -0
  312. package/src/components/xform/form-designer/setting-panel/property-editor/dropdownFlag-editor.vue +133 -0
  313. package/src/components/xform/form-designer/setting-panel/property-editor/dsName-editor.vue +1 -1
  314. package/src/components/xform/form-designer/setting-panel/property-editor/echartHeight-editor.vue +1 -1
  315. package/src/components/xform/form-designer/setting-panel/property-editor/endPlaceholder-editor.vue +1 -1
  316. package/src/components/xform/form-designer/setting-panel/property-editor/event-handler/eventMixin.js +2 -2
  317. package/src/components/xform/form-designer/setting-panel/property-editor/event-handler/onAfterConfirmFile-editor.vue +32 -0
  318. package/src/components/xform/form-designer/setting-panel/property-editor/event-handler/onClick-editor.vue +22 -7
  319. package/src/components/xform/form-designer/setting-panel/property-editor/field-accessUrl/accessUrl-editor.vue +2 -2
  320. package/src/components/xform/form-designer/setting-panel/property-editor/field-area-select/areaDataType-editor.vue +25 -0
  321. package/src/components/xform/form-designer/setting-panel/property-editor/field-area-select/areaMinLevel-editor.vue +50 -0
  322. package/src/components/xform/form-designer/setting-panel/property-editor/field-area-select/areaName-editor.vue +20 -0
  323. package/src/components/xform/form-designer/setting-panel/property-editor/field-autocomplete/autocomplete-vabSearchName-editor.vue +199 -0
  324. package/src/components/xform/form-designer/setting-panel/property-editor/field-baseAttachment/baseAttachment-fileTypes-editor.vue +23 -0
  325. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/addTableData-event-editor.vue +84 -85
  326. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/button-type-editor.vue +1 -1
  327. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/clickBindActions.js +262 -0
  328. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/clickBindEvent-editor.vue +97 -73
  329. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/form-host-event-editor.vue +188 -0
  330. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/icon-editor.vue +14 -15
  331. package/src/components/xform/form-designer/setting-panel/property-editor/field-button/search-dialog-event-editor.vue +237 -161
  332. package/src/components/xform/form-designer/setting-panel/property-editor/field-cascader/cascader-multiple-editor.vue +8 -3
  333. package/src/components/xform/form-designer/setting-panel/property-editor/field-cascader/checkStrictly-editor.vue +11 -13
  334. package/src/components/xform/form-designer/setting-panel/property-editor/field-cascader/showAllLevels-editor.vue +21 -0
  335. package/src/components/xform/form-designer/setting-panel/property-editor/field-common/keyName-editor.vue +74 -67
  336. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-dateLimit-editor.vue +179 -0
  337. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-defaultValue-editor.vue +21 -3
  338. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-format-editor.vue +1 -1
  339. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-type-editor.vue +1 -1
  340. package/src/components/xform/form-designer/setting-panel/property-editor/field-date/date-valueFormat-editor.vue +1 -1
  341. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultTime-editor.vue +27 -0
  342. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-defaultValue-editor.vue +1 -1
  343. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-format-editor.vue +1 -1
  344. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-type-editor.vue +1 -1
  345. package/src/components/xform/form-designer/setting-panel/property-editor/field-date-range/date-range-valueFormat-editor.vue +1 -1
  346. package/src/components/xform/form-designer/setting-panel/property-editor/field-divider/contentPosition-editor.vue +1 -1
  347. package/src/components/xform/form-designer/setting-panel/property-editor/field-dropdown-menu/dropdown-item-editor.vue +21 -0
  348. package/src/components/xform/form-designer/setting-panel/property-editor/field-dropdown-menu/dropdown-menu-editor.vue +59 -0
  349. package/src/components/xform/form-designer/setting-panel/property-editor/field-echart/echart-bar-editor.vue +187 -71
  350. package/src/components/xform/form-designer/setting-panel/property-editor/field-echart/echart-category-editor.vue +190 -88
  351. package/src/components/xform/form-designer/setting-panel/property-editor/field-echart/echart-pie-editor.vue +91 -46
  352. package/src/components/xform/form-designer/setting-panel/property-editor/field-file-upload/file-upload-fileTypes-editor.vue +44 -44
  353. package/src/components/xform/form-designer/setting-panel/property-editor/field-gantt/gantt-editor.vue +36 -0
  354. package/src/components/xform/form-designer/setting-panel/property-editor/field-html-text/htmlContent-editor.vue +29 -29
  355. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import-button-editor.vue +79 -22
  356. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +96 -0
  357. package/src/components/xform/form-designer/setting-panel/property-editor/field-number/controlsPosition-editor.vue +1 -1
  358. package/src/components/xform/form-designer/setting-panel/property-editor/field-picture-upload/picture-upload-fileTypes-editor.vue +44 -44
  359. package/src/components/xform/form-designer/setting-panel/property-editor/field-print-button/print-button-editor.vue +115 -86
  360. package/src/components/xform/form-designer/setting-panel/property-editor/field-print-button/print-detail-button-editor.vue +115 -0
  361. package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/highThreshold-editor.vue +1 -1
  362. package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/lowThreshold-editor.vue +1 -1
  363. package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/rate-defaultValue-editor.vue +2 -2
  364. package/src/components/xform/form-designer/setting-panel/property-editor/field-rate/rate-max-editor.vue +1 -1
  365. package/src/components/xform/form-designer/setting-panel/property-editor/field-script/script-editor.vue +4 -4
  366. package/src/components/xform/form-designer/setting-panel/property-editor/field-script-input/script-input-editor.vue +55 -0
  367. package/src/components/xform/form-designer/setting-panel/property-editor/field-static-text/fontSize-editor.vue +1 -1
  368. package/src/components/xform/form-designer/setting-panel/property-editor/field-static-text/preWrap-editor.vue +23 -0
  369. package/src/components/xform/form-designer/setting-panel/property-editor/field-static-text/textContent-editor.vue +2 -2
  370. package/src/components/xform/form-designer/setting-panel/property-editor/field-status/field-status-editor.vue +67 -41
  371. package/src/components/xform/form-designer/setting-panel/property-editor/field-switch/activeText-editor.vue +1 -1
  372. package/src/components/xform/form-designer/setting-panel/property-editor/field-switch/inactiveText-editor.vue +1 -1
  373. package/src/components/xform/form-designer/setting-panel/property-editor/field-switch/switchWidth-editor.vue +1 -1
  374. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-button-editor.vue +56 -0
  375. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-item-button-editor.vue +74 -0
  376. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/table-export-button-editor.vue +28 -9
  377. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-defaultValue-editor.vue +21 -3
  378. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-format-editor.vue +1 -1
  379. package/src/components/xform/form-designer/setting-panel/property-editor/field-time/time-timeLimit-editor.vue +53 -0
  380. package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-defaultValue-editor.vue +1 -1
  381. package/src/components/xform/form-designer/setting-panel/property-editor/field-time-range/time-range-format-editor.vue +1 -1
  382. package/src/components/xform/form-designer/setting-panel/property-editor/field-vabSearch/vabSearchField-editor.vue +2 -2
  383. package/src/components/xform/form-designer/setting-panel/property-editor/field-vabSearch/vabSearchName-editor.vue +15 -3
  384. package/src/components/xform/form-designer/setting-panel/property-editor/field-vabUpload/field-vabUpload-editor.vue +33 -1
  385. package/src/components/xform/form-designer/setting-panel/property-editor/field-vabUpload/vabUpload-fileTypes-editor.vue +23 -0
  386. package/src/components/xform/form-designer/setting-panel/property-editor/field-vabUpload2/field-vabUpload2-editor.vue +66 -0
  387. package/src/components/xform/form-designer/setting-panel/property-editor/field-vue-page/vue-page-editor.vue +48 -0
  388. package/src/components/xform/form-designer/setting-panel/property-editor/fileMaxSize-editor.vue +1 -1
  389. package/src/components/xform/form-designer/setting-panel/property-editor/fileTypesEditorMixin.js +116 -0
  390. package/src/components/xform/form-designer/setting-panel/property-editor/fileTypesSelect.vue +176 -0
  391. package/src/components/xform/form-designer/setting-panel/property-editor/formScriptEnabled-editor.vue +108 -19
  392. package/src/components/xform/form-designer/setting-panel/property-editor/formatType-editor.vue +137 -0
  393. package/src/components/xform/form-designer/setting-panel/property-editor/formula-editor.vue +972 -717
  394. package/src/components/xform/form-designer/setting-panel/property-editor/iconClass-editor.vue +1 -1
  395. package/src/components/xform/form-designer/setting-panel/property-editor/label-editor.vue +1 -1
  396. package/src/components/xform/form-designer/setting-panel/property-editor/labelAlign-editor.vue +1 -1
  397. package/src/components/xform/form-designer/setting-panel/property-editor/labelColor-editor.vue +21 -12
  398. package/src/components/xform/form-designer/setting-panel/property-editor/labelIconClass-editor.vue +17 -16
  399. package/src/components/xform/form-designer/setting-panel/property-editor/labelIconPosition-editor.vue +26 -26
  400. package/src/components/xform/form-designer/setting-panel/property-editor/labelTooltip-editor.vue +67 -13
  401. package/src/components/xform/form-designer/setting-panel/property-editor/labelWidth-editor.vue +1 -1
  402. package/src/components/xform/form-designer/setting-panel/property-editor/limit-editor.vue +2 -2
  403. package/src/components/xform/form-designer/setting-panel/property-editor/max-editor.vue +1 -1
  404. package/src/components/xform/form-designer/setting-panel/property-editor/maxLength-editor.vue +1 -1
  405. package/src/components/xform/form-designer/setting-panel/property-editor/min-editor.vue +1 -1
  406. package/src/components/xform/form-designer/setting-panel/property-editor/minLength-editor.vue +1 -1
  407. package/src/components/xform/form-designer/setting-panel/property-editor/multiple-editor.vue +19 -14
  408. package/src/components/xform/form-designer/setting-panel/property-editor/multipleLimit-editor.vue +2 -2
  409. package/src/components/xform/form-designer/setting-panel/property-editor/name-editor.vue +178 -101
  410. package/src/components/xform/form-designer/setting-panel/property-editor/oplog-editor.vue +31 -0
  411. package/src/components/xform/form-designer/setting-panel/property-editor/placeholder-editor.vue +2 -2
  412. package/src/components/xform/form-designer/setting-panel/property-editor/precision-editor.vue +2 -2
  413. package/src/components/xform/form-designer/setting-panel/property-editor/prefixIcon-editor.vue +14 -15
  414. package/src/components/xform/form-designer/setting-panel/property-editor/project-tag-editor.vue +349 -0
  415. package/src/components/xform/form-designer/setting-panel/property-editor/required-editor.vue +10 -6
  416. package/src/components/xform/form-designer/setting-panel/property-editor/requiredHint-editor.vue +4 -4
  417. package/src/components/xform/form-designer/setting-panel/property-editor/rows-editor.vue +1 -1
  418. package/src/components/xform/form-designer/setting-panel/property-editor/showRuleFlag-editor.vue +1 -1
  419. package/src/components/xform/form-designer/setting-panel/property-editor/showViewButton-editor.vue +29 -0
  420. package/src/components/xform/form-designer/setting-panel/property-editor/space-editor-editor.vue +1 -1
  421. package/src/components/xform/form-designer/setting-panel/property-editor/startPlaceholder-editor.vue +1 -1
  422. package/src/components/xform/form-designer/setting-panel/property-editor/step-editor.vue +1 -1
  423. package/src/components/xform/form-designer/setting-panel/property-editor/styleTableClass-editor.vue +1 -1
  424. package/src/components/xform/form-designer/setting-panel/property-editor/styleTitClass-editor.vue +1 -1
  425. package/src/components/xform/form-designer/setting-panel/property-editor/suffixIcon-editor.vue +14 -15
  426. package/src/components/xform/form-designer/setting-panel/property-editor/tempStorage-editor.vue +42 -0
  427. package/src/components/xform/form-designer/setting-panel/property-editor/textFlag-editor.vue +304 -19
  428. package/src/components/xform/form-designer/setting-panel/property-editor/type-editor.vue +1 -1
  429. package/src/components/xform/form-designer/setting-panel/property-editor/uploadTip-editor.vue +1 -1
  430. package/src/components/xform/form-designer/setting-panel/property-editor/uploadURL-editor.vue +1 -1
  431. package/src/components/xform/form-designer/setting-panel/property-editor/urlValueEnabled-editor.vue +91 -0
  432. package/src/components/xform/form-designer/setting-panel/property-editor/utcTransformEnabled-editor.vue +19 -0
  433. package/src/components/xform/form-designer/setting-panel/property-editor/validation-editor.vue +3 -3
  434. package/src/components/xform/form-designer/setting-panel/property-editor/validationHint-editor.vue +3 -3
  435. package/src/components/xform/form-designer/setting-panel/property-editor/wfFlag-editor.vue +372 -50
  436. package/src/components/xform/form-designer/setting-panel/property-editor/widgetShowRuleFlag-editor.vue +263 -0
  437. package/src/components/xform/form-designer/setting-panel/property-editor/widgetWidth-editor.vue +1 -1
  438. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +372 -322
  439. package/src/components/xform/form-designer/setting-panel/widgetPropertyDialogMixin.js +186 -0
  440. package/src/components/xform/form-designer/toolbar-panel/index.vue +267 -103
  441. package/src/components/xform/form-designer/toolbar-panel/indexMixin.js +655 -24
  442. package/src/components/xform/form-designer/widget-panel/index.vue +391 -321
  443. package/src/components/xform/form-designer/widget-panel/indexMixin.js +335 -2
  444. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +4609 -3092
  445. package/src/components/xform/form-render/compareDelList.vue +83 -0
  446. package/src/components/xform/form-render/compareView.vue +76 -0
  447. package/src/components/xform/form-render/container-item/containerItemMixin.js +404 -11
  448. package/src/components/xform/form-render/container-item/data-table-item.vue +221 -202
  449. package/src/components/xform/form-render/container-item/data-table-mixin copy.js +5910 -0
  450. package/src/components/xform/form-render/container-item/data-table-mixin.js +5846 -12
  451. package/src/components/xform/form-render/container-item/detail-h5-item.vue +173 -172
  452. package/src/components/xform/form-render/container-item/detail-item.vue +450 -158
  453. package/src/components/xform/form-render/container-item/detail-pane-item.vue +17 -3
  454. package/src/components/xform/form-render/container-item/detail-plain-item.vue +92 -0
  455. package/src/components/xform/form-render/container-item/dynamicFieldEngine.js +285 -0
  456. package/src/components/xform/form-render/container-item/dynamicFieldMixin.js +416 -0
  457. package/src/components/xform/form-render/container-item/grid-col-item.vue +10 -3
  458. package/src/components/xform/form-render/container-item/grid-item.vue +1 -1
  459. package/src/components/xform/form-render/container-item/list-h5-item.vue +1198 -419
  460. package/src/components/xform/form-render/container-item/sub-form-item.vue +10 -2
  461. package/src/components/xform/form-render/container-item/tab-item.vue +129 -88
  462. package/src/components/xform/form-render/container-item/table-cell-item.vue +38 -32
  463. package/src/components/xform/form-render/container-item/table-item.vue +7 -7
  464. package/src/components/xform/form-render/container-item/table2-cell-item.vue +53 -34
  465. package/src/components/xform/form-render/container-item/table2-item.vue +198 -99
  466. package/src/components/xform/form-render/container-item/tree-item.vue +32 -11
  467. package/src/components/xform/form-render/dynamicDialogRender.js +238 -3
  468. package/src/components/xform/form-render/dynamicDrawerRender.js +229 -0
  469. package/src/components/xform/form-render/formDynamicFieldMixin.js +131 -0
  470. package/src/components/xform/form-render/index.vue +79 -21
  471. package/src/components/xform/form-render/indexMixin.js +5295 -59
  472. package/src/components/xform/form-render/refMixin.js +34 -3
  473. package/src/components/xform/icon-picker/icons.json +284 -0
  474. package/src/components/xform/icon-picker/index.vue +145 -0
  475. package/src/components/xform/lang/en-US.js +470 -438
  476. package/src/components/xform/lang/en-US_extension.js +4 -0
  477. package/src/components/xform/lang/zh-CN.js +643 -593
  478. package/src/components/xform/mixins/defaultHandle.js +689 -2
  479. package/src/components/xform/mixins/scriptHttp.js +179 -3
  480. package/src/components/xform/utils/attachmentValueUtil.js +239 -0
  481. package/src/components/xform/utils/dynamicSchemaUtil.js +361 -0
  482. package/src/components/xform/utils/emitter.js +4 -4
  483. package/src/components/xform/utils/formHttp.js +162 -0
  484. package/src/components/xform/utils/format.js +205 -172
  485. package/src/components/xform/utils/formula-util.js +969 -0
  486. package/src/components/xform/utils/queryParamUtil.js +84 -0
  487. package/src/components/xform/utils/sfc-generator.js +2 -2
  488. package/src/components/xform/utils/smart-vue-i18n/index.js +2 -1
  489. package/src/components/xform/utils/tableCellValidateUtil.js +148 -0
  490. package/src/components/xform/utils/tableColumnHelper.js +155 -0
  491. package/src/components/xform/utils/textMaskUtil.js +179 -0
  492. package/src/components/xform/utils/treeTableUtil.js +1265 -0
  493. package/src/components/xform/utils/util.js +1640 -1
  494. package/src/components/xform/utils/validators.js +185 -4
  495. package/src/components/xform/utils/vue2js-generator.js +2 -2
  496. package/src/components/xhsPrint/index.js +44 -1
  497. package/src/components/xhsPrint/mixins.js +269 -1
  498. package/src/directive/LimitNumber/index.js +144 -1
  499. package/src/directive/el-dialog-center/index.js +34 -1
  500. package/src/directive/el-drag-dialog/drag.js +86 -1
  501. package/src/directive/el-readonly/index.js +15 -1
  502. package/src/directive/permission/hasPermi.js +34 -1
  503. package/src/index.js +403 -85
  504. package/src/lang/index.js +56 -51
  505. package/src/lang/locale/en/login.js +27 -0
  506. package/src/lang/locale/zh/login.js +26 -0
  507. package/src/layout/components/AppMain.vue +147 -111
  508. package/src/layout/components/Sidebar/default.vue +1655 -1222
  509. package/src/layout/components/Sidebar/index.vue +6 -1
  510. package/src/layout/components/TagsView/index.vue +57 -15
  511. package/src/layout/components/createCompany/createCompanyDialog.vue +157 -0
  512. package/src/layout/components/extractedCode/createDialog.vue +92 -0
  513. package/src/layout/components/extractedCode/queryDialog.vue +103 -0
  514. package/src/layout/components/extractedCode/viewDialog.vue +207 -0
  515. package/src/layout/components/langTool.vue +128 -120
  516. package/src/layout/components/watermark/index.vue +83 -0
  517. package/src/layout/defaultLayout.vue +170 -150
  518. package/src/microRouter/index.js +447 -0
  519. package/src/mixins/selectDialog/index.js +266 -1
  520. package/src/mixins/tableTree/index.js +262 -4
  521. package/src/mixins/wf/index.js +40 -6
  522. package/src/permission.js +158 -16
  523. package/src/public-path.js +38 -0
  524. package/src/resources/js/base/common.js +109 -109
  525. package/src/router/index.js +4 -7
  526. package/src/router/modules/customer.js +72 -4
  527. package/src/router/modules/system.js +4 -0
  528. package/src/store/config/index.js +945 -3
  529. package/src/store/getters.js +4 -1
  530. package/src/store/modules/micro.js +57 -0
  531. package/src/store/modules/permission.js +517 -23
  532. package/src/store/modules/settings.js +26 -1
  533. package/src/store/modules/tagsView.js +208 -5
  534. package/src/store/modules/user.js +418 -28
  535. package/src/utils/aes.js +21 -1
  536. package/src/utils/auth.js +27 -1
  537. package/src/utils/componentDialog.js +339 -0
  538. package/src/utils/global.js +370 -8
  539. package/src/utils/index.js +579 -7
  540. package/src/utils/keepAlive.js +185 -1
  541. package/src/utils/lazyPlugin.js +66 -0
  542. package/src/utils/menuAdapter.js +277 -0
  543. package/src/utils/pddLog.js +92 -0
  544. package/src/utils/pdfUtil.js +71 -0
  545. package/src/utils/repeatOpen.js +48 -0
  546. package/src/utils/request.js +403 -14
  547. package/src/utils/resolveViewComponent.js +203 -0
  548. package/src/utils/scrollUtil.js +25 -0
  549. package/src/utils/vab.js +1279 -27
  550. package/src/utils/validate.js +104 -1
  551. package/src/views/bd/project/branch/bd_branch/edit.vue +145 -0
  552. package/src/views/bd/project/branch/bd_branch/list.vue +72 -0
  553. package/src/views/bd/project/branch/bd_branch/menuKindDialog.vue +106 -0
  554. package/src/views/bd/project/branch/bd_branch/mixins/edit.js +189 -0
  555. package/src/views/bd/project/branch/bd_branch/mixins/list.js +124 -0
  556. package/src/views/bd/project/branch/bd_branch/mixins/menuKindDialog.js +85 -0
  557. package/src/views/bd/project/branch/form_script/list.vue +31 -0
  558. package/src/views/bd/project/branch/form_template/list.vue +30 -0
  559. package/src/views/bd/project/branch/menu_kind/list.vue +31 -0
  560. package/src/views/bd/project/common/form_script/list.vue +16 -0
  561. package/src/views/bd/project/common/form_template/list.vue +15 -0
  562. package/src/views/bd/project/common/menu_kind/list.vue +15 -0
  563. package/src/views/bd/project/core/branchContext.js +100 -0
  564. package/src/views/bd/project/core/branchPage.js +78 -0
  565. package/src/views/bd/project/core/branchPageWrap.vue +225 -0
  566. package/src/views/bd/project/core/branchScope.js +44 -0
  567. package/src/views/bd/project/core/branchSearchPage.js +285 -0
  568. package/src/views/bd/project/core/branchSelect.vue +85 -0
  569. package/src/views/bd/project/core/branchTreeBar.vue +81 -0
  570. package/src/views/bd/project/core/httpBranchPatch.js +58 -0
  571. package/src/views/bd/project/datatable/menu_kind/list.vue +15 -0
  572. package/src/views/bd/project/datatable/table_model/list.vue +15 -0
  573. package/src/views/bd/setting/bd_attach_setting/dialog.vue +1 -1
  574. package/src/views/bd/setting/bd_attach_setting/edit.vue +5 -5
  575. package/src/views/bd/setting/bd_attach_setting/list.vue +28 -55
  576. package/src/views/bd/setting/bd_attach_setting/mixins/dialog.js +84 -1
  577. package/src/views/bd/setting/bd_attach_setting/mixins/edit.js +116 -5
  578. package/src/views/bd/setting/bd_attach_setting/mixins/list.js +239 -1
  579. package/src/views/bd/setting/bd_company_env/dialog.vue +174 -0
  580. package/src/views/bd/setting/bd_company_env/edit.vue +193 -0
  581. package/src/views/bd/setting/bd_company_env/list.vue +175 -0
  582. package/src/views/bd/setting/config_manage/list.vue +83 -0
  583. package/src/views/bd/setting/formVersion/button.vue +60 -0
  584. package/src/views/bd/setting/formVersion/compareBasicSection.vue +125 -0
  585. package/src/views/bd/setting/formVersion/compareCodeSection.vue +539 -0
  586. package/src/views/bd/setting/formVersion/compareContMixin.scss +65 -0
  587. package/src/views/bd/setting/formVersion/compareContent.vue +63 -0
  588. package/src/views/bd/setting/formVersion/compareDialog.vue +88 -0
  589. package/src/views/bd/setting/formVersion/compareMixin.js +93 -0
  590. package/src/views/bd/setting/formVersion/fieldCompare.vue +54 -0
  591. package/src/views/bd/setting/formVersion/formScriptCompareView.vue +94 -0
  592. package/src/views/bd/setting/formVersion/formTemplateCompareView.vue +74 -0
  593. package/src/views/bd/setting/formVersion/ftHistoryDialog.vue +501 -0
  594. package/src/views/bd/setting/formVersion/link.vue +63 -0
  595. package/src/views/bd/setting/formVersion/preformDialog.vue +87 -0
  596. package/src/views/bd/setting/formVersion/reverButton.vue +82 -0
  597. package/src/views/bd/setting/formVersion/tableDetailDiff.js +99 -0
  598. package/src/views/bd/setting/formVersion/tableModelCompareView.vue +514 -0
  599. package/src/views/bd/setting/formVersion/textDiff.js +102 -0
  600. package/src/views/bd/setting/form_import_log/edit.vue +130 -0
  601. package/src/views/bd/setting/form_import_log/list.vue +211 -0
  602. package/src/views/bd/setting/form_script/dialog.vue +1 -1
  603. package/src/views/bd/setting/form_script/edit.vue +197 -74
  604. package/src/views/bd/setting/form_script/edit1.vue +411 -187
  605. package/src/views/bd/setting/form_script/form_list.vue +175 -85
  606. package/src/views/bd/setting/form_script/list.vue +96 -21
  607. package/src/views/bd/setting/form_script/list1.vue +207 -118
  608. package/src/views/bd/setting/form_script/mixins/dialog.js +130 -1
  609. package/src/views/bd/setting/form_script/mixins/edit.js +265 -7
  610. package/src/views/bd/setting/form_script/mixins/edit1.js +259 -9
  611. package/src/views/bd/setting/form_script/mixins/form_list.js +320 -4
  612. package/src/views/bd/setting/form_script/mixins/list.js +307 -4
  613. package/src/views/bd/setting/form_script/mixins/list1.js +512 -14
  614. package/src/views/bd/setting/form_script/mixins/list2.js +10 -1
  615. package/src/views/bd/setting/form_script/mixins/otherAuthDialog.js +194 -0
  616. package/src/views/bd/setting/form_script/mixins/preformDialog.js +34 -1
  617. package/src/views/bd/setting/form_script/otherAuthDialog.vue +83 -0
  618. package/src/views/bd/setting/form_template/batchWfObjConfigDialog.vue +105 -0
  619. package/src/views/bd/setting/form_template/dialog.vue +1 -1
  620. package/src/views/bd/setting/form_template/edit.vue +356 -184
  621. package/src/views/bd/setting/form_template/editWfObjConfigDialog.vue +2 -2
  622. package/src/views/bd/setting/form_template/formDesignerDialog.vue +172 -0
  623. package/src/views/bd/setting/form_template/ftHistoryDialog.vue +1 -1
  624. package/src/views/bd/setting/form_template/itemList.vue +1 -1
  625. package/src/views/bd/setting/form_template/list.vue +303 -212
  626. package/src/views/bd/setting/form_template/mixins/batchWfObjConfigDialog.js +282 -0
  627. package/src/views/bd/setting/form_template/mixins/dialog.js +103 -1
  628. package/src/views/bd/setting/form_template/mixins/edit.js +280 -9
  629. package/src/views/bd/setting/form_template/mixins/editWfObjConfigDialog.js +92 -1
  630. package/src/views/bd/setting/form_template/mixins/ftHistoryDialog.js +91 -1
  631. package/src/views/bd/setting/form_template/mixins/itemEdit.js +104 -1
  632. package/src/views/bd/setting/form_template/mixins/itemList.js +234 -1
  633. package/src/views/bd/setting/form_template/mixins/list.js +721 -22
  634. package/src/views/bd/setting/form_template/mixins/list2.js +411 -0
  635. package/src/views/bd/setting/form_template/mixins/otherAuthDialog.js +193 -0
  636. package/src/views/bd/setting/form_template/mixins/preformDialog.js +28 -3
  637. package/src/views/bd/setting/form_template/mixins/wf_list.js +430 -0
  638. package/src/views/bd/setting/form_template/otherAuthDialog.vue +83 -0
  639. package/src/views/bd/setting/form_template/wfObjConfigDialog.vue +253 -0
  640. package/src/views/bd/setting/form_template/wf_list.vue +161 -0
  641. package/src/views/bd/setting/logic_param/edit.vue +146 -0
  642. package/src/views/bd/setting/logic_param/edit1.vue +106 -0
  643. package/src/views/bd/setting/logic_param/edit2.vue +139 -0
  644. package/src/views/bd/setting/logic_param/list.vue +74 -0
  645. package/src/views/bd/setting/logic_param/list1.vue +12 -0
  646. package/src/views/bd/setting/logic_param/list2.vue +12 -0
  647. package/src/views/bd/setting/logic_param/mixins/edit.js +93 -0
  648. package/src/views/bd/setting/logic_param/mixins/list.js +376 -0
  649. package/src/views/bd/setting/menu_kind/authDialog.vue +1 -1
  650. package/src/views/bd/setting/menu_kind/dialog.vue +1 -1
  651. package/src/views/bd/setting/menu_kind/list.vue +172 -83
  652. package/src/views/bd/setting/menu_kind/mixins/authDialog.js +300 -7
  653. package/src/views/bd/setting/menu_kind/mixins/dialog.js +139 -1
  654. package/src/views/bd/setting/menu_kind/mixins/list.js +201 -1
  655. package/src/views/bd/setting/push_data/edit.vue +139 -0
  656. package/src/views/bd/setting/push_data/list.vue +283 -0
  657. package/src/views/bd/setting/push_data_h/edit.vue +153 -0
  658. package/src/views/bd/setting/push_data_h/list.vue +293 -0
  659. package/src/views/bd/setting/request_async_setting/edit.vue +320 -0
  660. package/src/views/bd/setting/request_async_setting/list.vue +372 -0
  661. package/src/views/bd/setting/request_setting/edit.vue +300 -0
  662. package/src/views/bd/setting/request_setting/list.vue +301 -0
  663. package/src/views/bd/setting/table_model/dialog.vue +1 -1
  664. package/src/views/bd/setting/table_model/edit.vue +1080 -426
  665. package/src/views/bd/setting/table_model/list.vue +219 -126
  666. package/src/views/bd/setting/table_model/mixins/dialog.js +71 -1
  667. package/src/views/bd/setting/table_model/mixins/edit.js +1309 -13
  668. package/src/views/bd/setting/table_model/mixins/list.js +475 -14
  669. package/src/views/bd/setting/table_model/mixins/otherAuthDialog.js +201 -0
  670. package/src/views/bd/setting/table_model/mixins/zdDialog.js +114 -3
  671. package/src/views/bd/setting/table_model/otherAuthDialog.vue +83 -0
  672. package/src/views/bd/setting/table_model/zdDialog.vue +1 -1
  673. package/src/views/bd/setting/utils/index.js +75 -1
  674. package/src/views/demo/bizTab/bill/billConfig.js +41 -0
  675. package/src/views/demo/bizTab/bill/detail.vue +436 -0
  676. package/src/views/demo/bizTab/bill/list.vue +288 -0
  677. package/src/views/demo/bizTab/bill/productDialog.vue +176 -0
  678. package/src/views/demo/bizTab/simple/billApi.js +123 -0
  679. package/src/views/demo/bizTab/simple/detail.vue +407 -0
  680. package/src/views/demo/bizTab/simple/list.vue +217 -0
  681. package/src/views/demo/bizTab/standalone/index.vue +121 -0
  682. package/src/views/demo/bizTab/wf/billConfig.js +44 -0
  683. package/src/views/demo/bizTab/wf/detail.vue +661 -0
  684. package/src/views/demo/bizTab/wf/list.vue +242 -0
  685. package/src/views/support/export_template/list.vue +1 -1
  686. package/src/views/support/form-dialog-demo/demoPickerDialog.vue +72 -0
  687. package/src/views/support/form-dialog-demo/index.vue +537 -0
  688. package/src/views/user/access_log/list.vue +418 -349
  689. package/src/views/user/access_log/list2.vue +1 -1
  690. package/src/views/user/api_request/list.vue +1 -1
  691. package/src/views/user/area/dialog.vue +235 -116
  692. package/src/views/user/area/list.vue +318 -0
  693. package/src/views/user/bill_setting/edit.vue +1 -1
  694. package/src/views/user/bill_setting/list.vue +2 -2
  695. package/src/views/user/bill_setting/userDialog.vue +1 -1
  696. package/src/views/user/code_rules/list.vue +1 -1
  697. package/src/views/user/commMenu/index.vue +2 -2
  698. package/src/views/user/common_attribute/itemEdit.vue +2 -2
  699. package/src/views/user/common_attribute/list.vue +7 -4
  700. package/src/views/user/common_script/edit.vue +1 -1
  701. package/src/views/user/common_script/list.vue +2 -2
  702. package/src/views/user/company_info/dialog.vue +195 -154
  703. package/src/views/user/company_info/edit.vue +149 -88
  704. package/src/views/user/country/dialog.vue +1 -1
  705. package/src/views/user/country/list.vue +1 -1
  706. package/src/views/user/data_type_setting/dialog.vue +1 -1
  707. package/src/views/user/extend_datasource/dialog.vue +5 -1
  708. package/src/views/user/extend_datasource/edit.vue +5 -1
  709. package/src/views/user/extend_datasource/list.vue +6 -2
  710. package/src/views/user/fieldTranslation/editDialog.vue +8 -8
  711. package/src/views/user/fieldTranslation/list.vue +34 -34
  712. package/src/views/user/field_values_invisible/list.vue +1 -1
  713. package/src/views/user/file_type/edit.vue +30 -1
  714. package/src/views/user/file_type/list.vue +29 -1
  715. package/src/views/user/file_view_area/list.vue +1 -1
  716. package/src/views/user/file_view_ins/list.vue +22 -1
  717. package/src/views/user/form/form_template/dialog.vue +1 -1
  718. package/src/views/user/form/form_template/itemList.vue +1 -1
  719. package/src/views/user/form/form_template/list.vue +1 -1
  720. package/src/views/user/form/form_template_field/dialog.vue +1 -1
  721. package/src/views/user/form/form_type/dialog.vue +1 -1
  722. package/src/views/user/form/form_type/list.vue +1 -1
  723. package/src/views/user/form/report_requestaccess/dialog.vue +1 -1
  724. package/src/views/user/form/report_requestaccess/list.vue +1 -1
  725. package/src/views/user/form/vform/designer.vue +821 -749
  726. package/src/views/user/form/vform/formFieldMapping.js +2 -3
  727. package/src/views/user/form/vform/out_render.vue +1 -1
  728. package/src/views/user/form/vform/render.vue +80 -52
  729. package/src/views/user/form/view/edit.vue +56 -37
  730. package/src/views/user/form/view/list.vue +475 -54
  731. package/src/views/user/groups/dialog.vue +1 -1
  732. package/src/views/user/groups/edit.vue +2 -0
  733. package/src/views/user/groups/list.vue +2 -1
  734. package/src/views/user/home/default.vue +1117 -979
  735. package/src/views/user/home/default2.vue +1158 -0
  736. package/src/views/user/home/dev.vue +29 -0
  737. package/src/views/user/home/index.vue +20 -16
  738. package/src/views/user/lang_tag/dialog.vue +1 -1
  739. package/src/views/user/lang_tag/list.vue +1 -1
  740. package/src/views/user/language_setting/list.vue +1 -1
  741. package/src/views/user/login/default.vue +167 -44
  742. package/src/views/user/login/index.vue +4 -6
  743. package/src/views/user/login/indexMixin.js +582 -380
  744. package/src/views/user/menu/list.vue +51 -2
  745. package/src/views/user/menuFallback/index.vue +123 -0
  746. package/src/views/user/mobile_menu/list.vue +1 -1
  747. package/src/views/user/notify_message/dialog.vue +65 -22
  748. package/src/views/user/notify_message/list.vue +1 -1
  749. package/src/views/user/notify_template/edit.vue +188 -187
  750. package/src/views/user/notify_template/edit2.vue +176 -0
  751. package/src/views/user/notify_template/list.vue +5 -2
  752. package/src/views/user/notify_template/list2.vue +190 -0
  753. package/src/views/user/oplog/list.vue +1 -1
  754. package/src/views/user/outLink/cc_form_view.vue +185 -0
  755. package/src/views/user/outLink/form_view.vue +202 -184
  756. package/src/views/user/outLink/index.vue +72 -11
  757. package/src/views/user/outLink/view.vue +37 -19
  758. package/src/views/user/position/dialog.vue +1 -1
  759. package/src/views/user/position/list.vue +5 -5
  760. package/src/views/user/project_tag/dialog.vue +10 -5
  761. package/src/views/user/project_tag/edit.vue +2 -2
  762. package/src/views/user/project_tag/list.vue +10 -5
  763. package/src/views/user/push_setting/list.vue +3 -3
  764. package/src/views/user/request_setting/edit.vue +258 -0
  765. package/src/views/user/request_setting/list.vue +248 -0
  766. package/src/views/user/role/authConfig.vue +89 -0
  767. package/src/views/user/role/dialog.vue +70 -48
  768. package/src/views/user/role/edit.vue +609 -429
  769. package/src/views/user/role/list.vue +5 -5
  770. package/src/views/user/sale_org/dialog.vue +2 -2
  771. package/src/views/user/sale_org/list.vue +5 -2
  772. package/src/views/user/system_notice/infoDialog.vue +61 -1
  773. package/src/views/user/system_notice/list.vue +1 -1
  774. package/src/views/user/system_parameter/list.vue +1 -1
  775. package/src/views/user/user/dialog.vue +47 -24
  776. package/src/views/user/user/edit.vue +1485 -1021
  777. package/src/views/user/user/form_dialog.vue +158 -0
  778. package/src/views/user/user/form_edit.vue +117 -49
  779. package/src/views/user/user/form_info.vue +210 -0
  780. package/src/views/user/user/form_list.vue +2 -1
  781. package/src/views/user/user/info.vue +253 -140
  782. package/src/views/user/user/list.vue +652 -570
  783. package/src/views/user/user/modifyPasswordDialog.vue +64 -53
  784. package/src/views/user/user_log_classify/list.vue +1 -1
  785. package/src/views/user/wf/iframe/index.vue +6 -1
  786. package/src/views/user/wf/iframe/index2.vue +6 -1
  787. package/src/views/user/wf/wfReport/index.vue +648 -0
  788. package/src/views/user/wf/wf_auto_submit_data/list.vue +4 -2
  789. package/src/views/user/wf/wf_manage/list.vue +683 -256
  790. package/src/views/user/wf/wf_manage/list2.vue +875 -0
  791. package/src/views/user/wf/wf_manage/wfContentDialog.vue +47 -22
  792. package/src/views/user/wf/wf_obj_config/dialog.vue +1 -1
  793. package/src/views/user/wf/wf_obj_config/importItemDialog.vue +109 -0
  794. package/src/views/user/wf/wf_obj_config/itemEdit.vue +25 -1
  795. package/src/views/user/wf/wf_obj_config/list.vue +139 -6
  796. package/src/views/user/wf/wf_obj_config/list_form.vue +1 -1
  797. package/src/views/user/wf/wf_obj_config/wfBizDataSettingDialog.vue +292 -0
  798. package/src/views/user/wf/wf_transfer_setting/edit.vue +282 -0
  799. package/src/views/user/wf/wf_transfer_setting/list.vue +319 -0
  800. package/src/views/user/workbench_menu/list.vue +555 -0
  801. package/src/components/excelExport/export-panel.js +0 -458
  802. package/src/components/xform/form-designer/form-widget/dialog/formDrawer.vue +0 -206
  803. package/src/components/xform/form-render/container-item/list-h5-item2.vue +0 -1347
  804. package/src/utils/wf.js +0 -21
@@ -0,0 +1,1427 @@
1
+ # 树表 rowField 收敛——最终落地方案
2
+
3
+ > 日期:2026-07-28
4
+ > 范围:xform `data-table` 且 `isTreeTable: true` 的编辑、复制与提交链路
5
+ > 状态:方案已定稿;本文是后续实现、测试和验收基线,不代表代码已经按本文完成
6
+ > 核心修正:`rowField` 是树关系键,不等同于数据库物理 ID;复制时不能一律把
7
+ > `node[rowField]` 改成 `row_*`
8
+
9
+ ## 1. 目标与边界
10
+
11
+ 本次改造要同时解决以下问题:
12
+
13
+ 1. `treeConfig.rowField`、`parentField`、`children`、`mapChildren` 在新增、编辑、
14
+ 复制、展开、排序和提交链路中使用同一套字段解析结果;
15
+ 2. 复制树表时清空原记录的物理 ID,避免覆盖原数据或产生主键冲突;
16
+ 3. `rowField` 是产品编码等业务键时保留原值,不擅自生成新的业务编码;
17
+ 4. `rowField` 是纯技术树键时,复制后允许生成新的 `row_*` 临时键,并同步重映射
18
+ 整棵子树的 `parentField`;
19
+ 5. 单行保存与整表提交使用同一套递归清洗规则;
20
+ 6. 平铺数据、嵌套数据、懒加载数据以及 VXE 的 `children`/`mapChildren` 双份引用
21
+ 都能正确组装,节点不丢失、不重复;
22
+ 7. 临时值、VXE 内部字段和旧单物理 ID 不进入最终提交对象;
23
+ 8. 所有提交前处理基于副本完成,不修改表格当前编辑态数据。
24
+
25
+ 本次不改变后端的树结构协议,不修改通用的
26
+ `src/resources/js/base/common.js`,也不把业务编码生成职责移到通用树表组件。
27
+
28
+ ## 2. 标识语义必须拆开
29
+
30
+ | 名称 | 示例 | 职责 | 复制规则 |
31
+ |---|---|---|---|
32
+ | 物理 ID `physicalIdField` | `id: 10086` | 数据库记录身份、更新/删除定位 | 一律清空 |
33
+ | 业务树键 `rowField` | `code: "P001"` | 产品编码等有业务含义且被父字段引用的值 | 默认保留 |
34
+ | 技术树键 `rowField` | `nodeKey: "N001"` | 仅用于前端或后端挂树,无业务含义 | 可重新生成 |
35
+ | 父键 `parentField` | `parentCode: "P001"` | 引用父节点的 `rowField` 值 | 随树键策略同步 |
36
+ | VXE 行键 `_X_ROW_KEY` | 内部值 | 当前表格实例定位 | 不提交、不主动重建 |
37
+ | 前端临时树键标记 | `_X_TREE_TEMP_KEY` | 精确标识哪个 `rowField` 值是前端临时值 | 不提交 |
38
+
39
+ 从本方案开始,代码和文档中不再把 `rowField` 命名为 `idField`。两者名称混用正是
40
+ “产品编码被当作物理 ID 重新生成”的根因之一。
41
+
42
+ ### 2.1 产品编码场景
43
+
44
+ 配置如下:
45
+
46
+ ```js
47
+ treeConfig: {
48
+ rowField: "code",
49
+ parentField: "parentCode",
50
+ children: "children",
51
+ transform: true,
52
+ }
53
+ ```
54
+
55
+ 原节点:
56
+
57
+ ```js
58
+ { id: 100, code: "P001", parentCode: null }
59
+ ```
60
+
61
+ 复制后的正确结果是:
62
+
63
+ ```js
64
+ { id: null, code: "P001", parentCode: null }
65
+ ```
66
+
67
+ 即:清空物理 `id`,保留产品编码 `code`。禁止把 `code` 改成 `row_*`。
68
+
69
+ ### 2.2 使用业务键作为 rowField 的前置条件
70
+
71
+ `rowField` 在一张树表的有效数据范围内必须唯一、非空且稳定。如果产品编码允许重复、
72
+ 尚未确定,或者编辑过程中可能频繁变化,就不适合直接作为 `rowField`,应新增独立的
73
+ 技术树键,例如:
74
+
75
+ ```js
76
+ treeConfig: {
77
+ rowField: "f_tree_key",
78
+ parentField: "f_parent_key",
79
+ }
80
+ ```
81
+
82
+ 产品编码继续保存在 `code`,不再承担树关系身份。
83
+
84
+ ### 2.3 字面量 id 的兼容边界
85
+
86
+ 现有通用表单清洗和请求层会把字面量字段 `id` 中的 `row_*` 识别为临时物理 ID。
87
+ 本次不修改该跨项目约定,因此 xform 树表强制:
88
+
89
+ ```js
90
+ rowField === "id" => physicalIdField === "id"
91
+ ```
92
+
93
+ 禁止把字面量 `id` 配成另一个业务键,同时把物理 ID 指向其他字段。若业务编码可能是
94
+ `row_001`,字段必须命名为 `code` 等非 `id` 名称。配置校验发现该不安全组合时应中止
95
+ 初始化,而不是期待树表清洗器绕过请求层的二次处理。
96
+
97
+ ## 3. 最终配置契约
98
+
99
+ ### 3.1 treeConfig 是树结构唯一事实源
100
+
101
+ 系统默认、宿主 `dataTableOption.config.treeConfig` 和表单脚本
102
+ `tableConfig.config.treeConfig` 合并后,只生成一次 `resolvedTreeConfig`:
103
+
104
+ ```js
105
+ {
106
+ rowField,
107
+ parentField,
108
+ children,
109
+ mapChildren,
110
+ hasChild,
111
+ lazy,
112
+ transform,
113
+ }
114
+ ```
115
+
116
+ 初始化前的数据规范化使用 `resolvedTreeConfig`;同一配置随后写入
117
+ `tableOption.config.treeConfig` 创建 VXE。表格挂载后再校验
118
+ `$grid.treeConfig` 与 `resolvedTreeConfig` 的关键字段完全一致。
119
+
120
+ 因此,唯一事实源是“合并完成的 `resolvedTreeConfig`”,不是尚未创建的 `$grid`。
121
+ 挂载后的新增、复制、展开、排序和提交可读取 `$grid.treeConfig`,但不得再次自行合并
122
+ 或推导另一套字段。
123
+
124
+ 禁止在新增、复制、展开、排序或提交逻辑中写死 `id`、`f_parent`、
125
+ `f_children`。
126
+
127
+ xform 基础配置必须显式声明:
128
+
129
+ ```js
130
+ mapChildren: "_X_ROW_CHILD"
131
+ ```
132
+
133
+ 不能只依赖 VXE 全局 `treeOpts` 的隐式默认值。配置合并完成后,
134
+ `resolveTreeFields(resolvedTreeConfig)` 读取最终有效配置,并同时覆盖默认和自定义
135
+ `mapChildren` 场景。
136
+
137
+ ### 3.2 新增 xform 专用身份、复制与提交配置
138
+
139
+ ```js
140
+ treeIdentityConfig: {
141
+ physicalIdField: "id",
142
+ // 保持现有 xform 新增根节点协议
143
+ rootParentValue: 0,
144
+ // 未配置时仅在 rowField === physicalIdField 时视为 true
145
+ serverGeneratesRowField: undefined,
146
+ persistedRowFieldChangeStrategy: "reject",
147
+ changePersistedRowField: null,
148
+ validateExternalParentKey: null,
149
+ },
150
+
151
+ treeCopyConfig: {
152
+ // 未配置时按 rowField 与 physicalIdField 的关系自动推导
153
+ rowFieldStrategy: undefined,
154
+ orphanParentStrategy: "detach",
155
+ lazyStrategy: "reject",
156
+ generateRowField: null,
157
+ },
158
+
159
+ treeSubmitConfig: {
160
+ orphanParentStrategy: "preserve",
161
+ unloadedChildrenStrategy: "reject",
162
+ successReconcileStrategy: "reload",
163
+ },
164
+ ```
165
+
166
+ 字段含义:
167
+
168
+ | 字段 | 可选值 | 含义 |
169
+ |---|---|---|
170
+ | `treeIdentityConfig.physicalIdField` | 字段名 | 数据库物理 ID,默认 `id`;供复制、持久化判断和提交清洗共同使用 |
171
+ | `treeIdentityConfig.rootParentValue` | `null` / `0` / `"0"` 等 | 新增、复制脱离和规范提交时统一写出的根父值;默认 `0`,保持现有 xform 协议 |
172
+ | `treeIdentityConfig.serverGeneratesRowField` | `true` / `false` | 临时树键提交时能否清空并由服务端生成;默认仅在 `rowField === physicalIdField` 时为 `true` |
173
+ | `treeIdentityConfig.persistedRowFieldChangeStrategy` | `reject` / `transactional` | 已持久化业务树键能否修改;默认禁止 |
174
+ | `treeIdentityConfig.changePersistedRowField` | 函数 | `transactional` 时必填,由后端事务更新父节点键及全部子引用 |
175
+ | `treeIdentityConfig.validateExternalParentKey` | 函数 | 可选;确认不在当前节点集合中的父键是正式外部键 |
176
+ | `treeCopyConfig.rowFieldStrategy` | `preserve` / `regenerate` / `custom` | 复制时如何处理树关系键;未配置时自动推导 |
177
+ | `treeCopyConfig.orphanParentStrategy` | `detach` / `preserve` | 复制范围不包含原父节点时,转为根或保留外部父引用 |
178
+ | `treeCopyConfig.lazyStrategy` | `reject` / `loadAll` | 复制范围含未加载后代时拒绝,或先递归加载完整子树 |
179
+ | `treeCopyConfig.generateRowField` | 函数 | `custom` 必填;`regenerate` 可用它生成正式键 |
180
+ | `treeSubmitConfig.orphanParentStrategy` | `preserve` / `reject` | 正常提交遇到集合外父引用时保留或阻止提交 |
181
+ | `treeSubmitConfig.unloadedChildrenStrategy` | `reject` / `loadAll` / `omit` | 未加载后代的提交策略;`omit` 仅在后端明确支持部分树语义时启用 |
182
+ | `treeSubmitConfig.successReconcileStrategy` | `reload` | 服务端生成任一物理/树身份后恢复编辑态;本次落地只支持强制重新加载 |
183
+
184
+ 默认策略按字段语义推导:
185
+
186
+ ```js
187
+ const strategy =
188
+ configuredStrategy ??
189
+ (rowField === physicalIdField ? "regenerate" : "preserve");
190
+ ```
191
+
192
+ 因此:
193
+
194
+ - 默认 `rowField: "id"` 时,复制节点会先快照旧键,再生成新的临时树键;
195
+ - `rowField: "code"`、`physicalIdField: "id"` 时,复制节点保留 `code`,
196
+ 只清空 `id`;
197
+ - 业务确有特殊规则时,显式使用 `custom`,不通过字段名前缀猜测。
198
+
199
+ 当 `rowField === physicalIdField` 时增加不可绕过的配置守卫:
200
+
201
+ - 禁止显式 `preserve`,否则会把旧物理 ID 清空后又原样写回;
202
+ - 本次落地只允许生成带 `_X_TREE_TEMP_KEY` 的新临时键,并要求
203
+ `serverGeneratesRowField: true`;
204
+ - 暂不允许生成无临时标记的客户端永久主键,因为现有持久化判断按
205
+ `physicalIdField` 是否有值执行,会把复制行误判为已落库;
206
+ - 如果未来要支持客户端生成永久物理主键,必须另行引入独立新行状态或
207
+ `isPersistedRow` 回调,不能仅扩展生成器。
208
+
209
+ `custom` 以及带生成器的 `regenerate` 回调建议签名:
210
+
211
+ ```js
212
+ generateRowField({
213
+ node,
214
+ oldValue,
215
+ parentNode,
216
+ oldParentKey,
217
+ newParentKey,
218
+ parentCopy,
219
+ fields,
220
+ makeTempKey,
221
+ })
222
+ ```
223
+
224
+ `parentNode` 指原父节点,`parentCopy` 指已经生成的新父副本;根节点的
225
+ `newParentKey` 为 `rootParentValue`,复制范围外父节点按 orphan 策略得到正式外部键
226
+ 或根值。
227
+
228
+ 回调返回:
229
+
230
+ ```js
231
+ { value: "new-value", temporary: false }
232
+ ```
233
+
234
+ 也可直接返回原始值;原始值默认视为正式值。返回临时值时必须显式设置
235
+ `temporary: true`。`regenerate` 未提供生成器时才使用默认 `row_*` 临时键。
236
+ 当 `serverGeneratesRowField: false` 时,提交前仍为临时键必须阻止提交;
237
+ `regenerate` 必须通过生成器返回永久值。
238
+
239
+ `generateRowField` 必须是同步函数,返回 Promise 视为配置错误。需要后端号段时,
240
+ 复制 UI 先 `await resolveGeneratedRowFields()` 批量取得号段,再把预取 Map 或同步
241
+ allocator 传给纯函数 `copyTreeData()`;网络请求不能藏进同步生成器。
242
+
243
+ `validateExternalParentKey` 同样只允许同步返回严格 boolean。需要远程确认时,UI 在
244
+ 复制/提交 preflight 阶段先批量 `await` 校验并填充 `knownFormalKeyRegistry`;
245
+ 纯函数收到 Promise 必须报配置错误,不能把 truthy Promise 当成校验通过。
246
+
247
+ 配置优先级:
248
+
249
+ ```text
250
+ 系统默认
251
+ < 宿主 dataTableOption.treeIdentityConfig / treeCopyConfig / treeSubmitConfig
252
+ < 表单脚本 tableConfig.treeIdentityConfig / treeCopyConfig / treeSubmitConfig
253
+ ```
254
+
255
+ 三项配置都是 xform 业务配置,不塞入 VXE 的 `config.treeConfig`。
256
+
257
+ ## 4. 根节点、类型和 transform 约束
258
+
259
+ ### 4.1 根父值
260
+
261
+ 统一根父值口径:
262
+
263
+ ```js
264
+ null
265
+ undefined
266
+ ""
267
+ 0
268
+ "0"
269
+ ```
270
+
271
+ 因此,真实 `rowField` 值不得使用 `0`、`"0"` 或空值;否则无法同时表达
272
+ “真实节点键”和“根节点哨兵”。
273
+
274
+ 上面五种值是读取兼容口径;新增、复制脱离以及规范提交统一写
275
+ `treeIdentityConfig.rootParentValue`。配置为 `0` 或 `"0"` 的旧接口可保持原协议,
276
+ 但同一张表内不得混用多个根输出值。
277
+
278
+ 配置合并时必须满足:
279
+
280
+ ```js
281
+ isRootParent(rootParentValue) === true
282
+ ```
283
+
284
+ `-1`、`"ROOT"` 等读取口径无法识别的值应中止初始化,不能写出后再被下一轮当作孤儿。
285
+
286
+ ### 4.2 类型归一
287
+
288
+ VXE/xe-utils 的部分建树路径使用严格比较,仅在提交时 `String()` 比较并不能修复
289
+ 显示阶段的 number/string 分叉。数据进入 VXE 前应执行一次关系归一:
290
+
291
+ 1. 以 `normalizeTreeKey(value)` 建立规范键索引;
292
+ 2. `1` 与 `"1"` 视为同一关系键,若两者同时作为 `rowField` 出现则判为冲突;
293
+ 3. 当 `parentField: "1"` 唯一匹配到 `rowField: 1` 时,把父字段规范为实际父键值
294
+ `1`,使值和类型完全一致;
295
+ 4. 找不到父节点的真实外部父键保留原值;
296
+ 5. 归一只能在数据装载、插入或显式键变更时执行,不能只在提交出口补救。
297
+
298
+ ### 4.3 入表前统一为规范平铺模型
299
+
300
+ `transform: true` 接收的事实源必须是规范平铺数组。初始加载、`setValue`、复制插入和
301
+ 懒加载返回值进入 VXE 前统一执行:
302
+
303
+ 1. 遍历平铺、`children`、`mapChildren` 的每一次节点 occurrence;每次先记录
304
+ `(容器父节点, 当前节点)` 嵌套边,再判断节点是否已经见过;
305
+ 2. `WeakSet` 只阻止同一对象的 payload 重复收集和子树重复递归,不能删除第二个
306
+ 容器产生的 occurrence 边;因此同一对象挂在两个父节点下或挂到自身 children
307
+ 仍会被后续图校验发现;
308
+ 3. 规范化 `rowField` 是唯一主身份,缺失、根哨兵或重复都按树契约处理,不能用
309
+ 其他字段替代;
310
+ 4. `_X_ROW_KEY` 和已持久化物理 ID 只建立独立的交叉校验索引:任一辅助标识同时
311
+ 指向两个不同 `rowField`,或同一 `rowField` 的多实例携带冲突物理 ID,立即失败;
312
+ 5. 同一规范 `rowField` 出现多个对象实例时,以 `fullData`/显式平铺对象为优先来源;
313
+ 除 children 容器外的业务字段不一致则直接报冲突,不能静默覆盖;
314
+ 6. 规范化后的 `parentField` 是父子关系权威;
315
+ 7. 嵌套边只用于补全“没有 `parentField` 属性”的 nested-only 节点;
316
+ 8. 节点显式父键与嵌套位置冲突、同一节点存在多个父节点、自指或形成有向环时,
317
+ 中止装载并给出节点键;
318
+ 9. 补齐父键、统一值类型后移除旧 children 容器,输出唯一平铺数组;
319
+ 10. 原始入参不修改,规范数组作为后续 VXE 模型。
320
+
321
+ 不能把嵌套原数据直接交给 VXE transform 后再补救,因为建树过程可能覆盖原
322
+ `children` 并导致尚未平铺的后代丢失。
323
+
324
+ ### 4.4 transform
325
+
326
+ xform 树表当前所有提交与编辑语义都建立在 `transform: true` 上,因此它是强约束,
327
+ 不是可选能力:
328
+
329
+ - 默认配置显式写入 `transform: true`;
330
+ - 宿主配置和表单脚本合并完成后再次校验;
331
+ - 发现 `false` 时记录明确错误并强制恢复为 `true`,避免平铺子节点提交丢失;
332
+ - `rowField`、`parentField`、`children`、`mapChildren`、`hasChild` 必须存在且互不相同;
333
+ - `physicalIdField` 仅允许与 `rowField` 相同,不得等于父键、children 容器、
334
+ `hasChild` 或 `_X_TREE_TEMP_KEY` 等内部保留字段;
335
+ - 任一业务字段不得使用 `_X_ROW_KEY`、`_X_ROW_CHILD`、`_X_TREE_TEMP_KEY`
336
+ 等内部保留名;
337
+ - 字段缺失或碰撞时中止树表初始化并给出所有冲突字段。
338
+
339
+ ## 5. 公共树工具
340
+
341
+ 新增:
342
+
343
+ ```text
344
+ src/components/xform/utils/treeTableUtil.js
345
+ ```
346
+
347
+ 该文件只承载无 UI、可单测的纯函数:
348
+
349
+ ```js
350
+ resolveTreeFields(treeConfig)
351
+ resolveTreeIdentityConfig(context)
352
+ resolveTreeCopyConfig(context)
353
+ resolveTreeSubmitConfig(context)
354
+ isRootParent(value)
355
+ normalizeTreeKey(value)
356
+ treeKeyEquals(left, right)
357
+ getTreeNodeIdentity(row, context)
358
+ normalizeTreeRelations(rows, fields)
359
+ collectTreeNodes(sources, fields)
360
+ validateTreeGraph(nodes, edges, context)
361
+ canonicalizeTreeInput(sources, context)
362
+ getTreeLoadState(row, context)
363
+ syncTreeKeyReferences(rows, oldValue, newValue, fields)
364
+ copyTreeData(source, fields, copyConfig)
365
+ sanitizeTreeRow(row, context)
366
+ buildTreeSubmitData(sources, context)
367
+ ```
368
+
369
+ 上述工具全部保持同步、无网络副作用。`loadAll` 的递归请求由组件编排层负责,不放进
370
+ `buildTreeSubmitData()`、`copyTreeData()` 或 `getSubData2()`。
371
+
372
+ `resolveTreeFields()` 返回:
373
+
374
+ ```js
375
+ {
376
+ rowField,
377
+ parentField,
378
+ childrenField,
379
+ mapChildrenField,
380
+ hasChildField,
381
+ lazy,
382
+ }
383
+ ```
384
+
385
+ 这里明确使用 `rowField`,不再返回有歧义的 `idField`。
386
+
387
+ ## 6. 临时树键协议
388
+
389
+ ### 6.1 生成
390
+
391
+ 新增节点缺少正式 `rowField` 时:
392
+
393
+ ```js
394
+ const tempKey = `row_${uniqueValue}`;
395
+ row[rowField] = tempKey;
396
+ row._X_TREE_TEMP_KEY = tempKey;
397
+ ```
398
+
399
+ 每张树表同时维护不进入表单数据的 `temporaryKeyRegistry`。所有新临时键先注册再使用;
400
+ 正式值回填或行删除后注销。服务端装载数据中的正式树键/外部父键记录在
401
+ `knownFormalKeyRegistry`,供孤儿父键校验使用。
402
+
403
+ 判断临时值必须同时满足:
404
+
405
+ ```js
406
+ row[rowField] === row._X_TREE_TEMP_KEY
407
+ ```
408
+
409
+ 不能再把“字符串以 `row_` 开头”作为通用判断,因为合法产品编码也可能叫
410
+ `row_001`。
411
+
412
+ ### 6.2 正式值回填
413
+
414
+ 当产品选择器或父节点保存响应把临时键替换为正式值时:
415
+
416
+ 1. 校验新值不为空、不属于根哨兵,并在当前树中唯一;
417
+ 2. 找出所有 `parentField` 指向旧临时键的直接子节点;
418
+ 3. 把这些父引用同步改成新业务键;
419
+ 4. 删除 `_X_TREE_TEMP_KEY`;
420
+ 5. 刷新 VXE 树关系,但保留现有 `_X_ROW_KEY` 和当前编辑/展开状态。
421
+
422
+ 如果新值冲突,拒绝本次替换并给出业务提示,不能偷偷生成另一个编码。
423
+ 当 `rowField === physicalIdField` 时,父节点保存成功后必须先从响应读取正式物理 ID,
424
+ 完成“旧临时键 -> 新 ID”的整表引用同步,再允许保存其子节点。
425
+
426
+ ### 6.3 兼容旧数据
427
+
428
+ 历史代码可能只写入了 `row_*`,没有 `_X_TREE_TEMP_KEY`。兼容规则仅允许:
429
+
430
+ - `rowField === physicalIdField === "id"` 时,旧 `id` 的 `row_*` 前缀可作为一次性
431
+ 兼容清洗;
432
+ - 自定义 `rowField` 不使用前缀兜底,防止清掉合法业务值;
433
+ - 新代码生成的临时树键必须带显式标记。
434
+
435
+ ## 7. 新增与编辑流程
436
+
437
+ ### 7.1 新增根节点
438
+
439
+ 1. 解析最终 `treeConfig`;
440
+ 2. 创建表单默认行;
441
+ 3. 若业务已经提供合法 `rowField`,直接使用且不加临时标记;
442
+ 4. 否则生成带 `_X_TREE_TEMP_KEY` 的临时树键;
443
+ 5. `parentField` 写 `treeIdentityConfig.rootParentValue`;
444
+ 6. 插入 VXE 后恢复激活行。
445
+
446
+ ### 7.2 新增子节点
447
+
448
+ 除上述步骤外:
449
+
450
+ ```js
451
+ child[parentField] = parent[rowField];
452
+ ```
453
+
454
+ 父节点的 `rowField` 为空、冲突或尚未完成归一时禁止新增子节点。
455
+
456
+ ### 7.3 编辑 rowField
457
+
458
+ `rowField` 改动不是普通单元格赋值,必须走统一入口:
459
+
460
+ ```js
461
+ changeTreeRowField(row, newValue)
462
+ ```
463
+
464
+ 该入口负责唯一性校验、子节点父引用同步、临时标记清除以及树状态刷新。
465
+
466
+ 可编辑边界:
467
+
468
+ - 新增、尚未持久化的行:允许把临时键替换为正式业务键,并同步当前子节点;
469
+ - `rowField === physicalIdField` 且行已持久化:物理主键不可编辑,直接拒绝;
470
+ - `rowField !== physicalIdField` 且行已持久化:默认
471
+ `persistedRowFieldChangeStrategy: "reject"`,不能只保存父行;
472
+ - 业务必须修改已持久化树键时,只能使用 `transactional`:
473
+ `changePersistedRowField` 由后端在一个事务中更新父节点树键及所有直接子节点
474
+ `parentField`,包括前端尚未懒加载的子节点;接口成功后前端再同步已加载行并刷新树;
475
+ - 事务失败时保留旧键和旧父引用,不能出现父行已更新、子行仍指旧键的半成功状态。
476
+
477
+ 普通单行保存接口不得承担已持久化树键变更。
478
+
479
+ ## 8. 复制流程
480
+
481
+ 复制分两遍完成,禁止边递归边改父键。
482
+
483
+ ### 8.1 收集节点
484
+
485
+ `collectTreeNodes()` 同时接受:
486
+
487
+ - VXE `fullData`(transform 下通常是树根数组,需要递归收集);
488
+ - `childrenField` 嵌套节点;
489
+ - `mapChildrenField` 懒加载/映射节点。
490
+
491
+ 复制前先结合 `hasChildField` 和 VXE 懒加载状态判断完整性:
492
+
493
+ - `lazy: false` 时当前规范快照视为完整,不根据 `hasChildField` 推断缺失;
494
+ - `lazy: true` 时只认 `isTreeNodeLoaded(row)` 的状态,不用 children 长度猜测;
495
+ - 节点声明有子项但尚未加载时,默认 `lazyStrategy: "reject"`,整次复制不执行;
496
+ - `lazyStrategy: "loadAll"` 时,先递归等待所有目标后代加载完成,再从统一快照复制;
497
+ - 缺少 loader 或任一加载失败时按 `reject` 处理;
498
+ - 不提供“悄悄复制当前可见部分”的默认行为,避免生成残树。
499
+
500
+ 去重分两层:
501
+
502
+ 1. 每次访问节点先记录 occurrence 父边;`WeakSet` 只去除同一对象的重复 payload
503
+ 和重复递归,不去除第二个容器父边;
504
+ 2. 以规范化 `rowField` 为逻辑主身份合并不同对象实例;`_X_ROW_KEY` 和已持久化
505
+ 物理 ID 只做交叉一致性校验,不作为复合键,也不覆盖 `rowField` 唯一约束。
506
+
507
+ 多实例的业务字段一致时只保留权威平铺实例;内容冲突、同键不同物理 ID 或同一节点
508
+ 出现多个父边时终止复制,不能任选一份数据。
509
+
510
+ 收集结束后先完成父边冲突、自指和环校验,再生成父节点优先的拓扑顺序。生成器不得
511
+ 按原数组偶然顺序执行。
512
+
513
+ ### 8.2 第一遍:生成节点映射
514
+
515
+ 在清空任何字段之前,先对全部原节点建立不可变快照:
516
+
517
+ ```js
518
+ {
519
+ oldRowKey: node[rowField],
520
+ oldParentKey: node[parentField],
521
+ oldPhysicalId: node[physicalIdField],
522
+ }
523
+ ```
524
+
525
+ 然后按父到子的拓扑顺序对每个快照创建副本。调用子节点生成器前,内部父节点的
526
+ `newRowKey` 和 `parentCopy` 必须已经存在:
527
+
528
+ 1. 先按快照和 orphan 策略确定 `resolvedNewParentKey`:根节点使用
529
+ `rootParentValue`,内部父节点读取已建立的映射,外部父节点完成正式性校验或转根;
530
+ 2. 把 `resolvedNewParentKey` 作为 `newParentKey`,基于 `oldRowKey`
531
+ 按 `rowFieldStrategy` 计算
532
+ `{ value: newRowKey, temporary }`;
533
+ 3. 清空 `physicalIdField`;
534
+ 4. 删除源节点带来的 `_X_ROW_KEY`、`_X_ROW_CHILD`、旧 `_X_TREE_TEMP_KEY`
535
+ 等内部字段;
536
+ 5. 把 `newRowKey` 写回副本的 `rowField`;当两字段相同时,该步骤必须发生在
537
+ 清空物理 ID 之后;
538
+ 6. 当 `temporary: true` 时显式写
539
+ `copy._X_TREE_TEMP_KEY = newRowKey`;正式值保持无标记;
540
+ 7. 清空创建人、创建时间、更新人、更新时间等复制态字段;
541
+ 8. 建立 `oldRowKey -> newRowKey` 映射,并把 `resolvedNewParentKey` 存入副本上下文。
542
+
543
+ 所有父引用重映射只能读取快照,不能读取已经清洗的副本。该顺序专门保证默认
544
+ `rowField === physicalIdField === "id"` 的多层树不会断链。
545
+
546
+ 第一遍结束后必须校验所有 `newRowKey` 在复制集合内唯一;复制插入现有表时还要与
547
+ 目标表当前全部 `rowField` 做全局唯一性校验。生成器发生碰撞时整次复制失败,不能
548
+ 覆盖映射或只保留其中一个节点。
549
+
550
+ 策略行为:
551
+
552
+ | 策略 | rowField 处理 | 典型场景 |
553
+ |---|---|---|
554
+ | `preserve` | 保留原值,不加临时标记 | 产品编码、组织编码等业务键 |
555
+ | `regenerate` | 默认生成带标记的 `row_*`;配置生成器时也可产生永久键 | 纯技术树键或 `rowField === physicalIdField` |
556
+ | `custom` | 使用业务回调结果 | 后端号段、组合键等特殊规则 |
557
+
558
+ `preserve` 只接受已经确认的正式源树键。若源节点满足
559
+ `node[rowField] === node._X_TREE_TEMP_KEY`,或源键命中 `temporaryKeyRegistry`,
560
+ 复制必须失败并提示先完成业务选择/保存;也可以由调用方明确改用
561
+ `regenerate`/`custom` 生成新键。不得删除源 marker 后把原临时值当作正式键。
562
+
563
+ 如果是“同一张表内复制子树”,`preserve` 导致键冲突时必须拒绝插入并提示;
564
+ 不能为绕过冲突而静默改变产品编码。
565
+
566
+ ### 8.3 第二遍:重建父引用
567
+
568
+ 第一遍已经在调用生成器前得到 `resolvedNewParentKey`。第二遍只把它写入副本
569
+ `parentField` 并做整体验证;第一遍的决策规则如下:
570
+
571
+ 1. 原父节点也在复制集合中:使用映射后的新父键;
572
+ 2. 原父节点不在复制集合中且策略为 `detach`:改为
573
+ `treeIdentityConfig.rootParentValue`;
574
+ 3. 原父节点不在复制集合中且策略为 `preserve`:仅当父键在
575
+ `knownFormalKeyRegistry` 中,或 `validateExternalParentKey` 明确通过时保留;
576
+ 4. 外部父键命中 `temporaryKeyRegistry` 时拒绝复制并要求把父节点纳入复制范围或
577
+ 先保存父节点;未知来源的父键默认拒绝,不能按 `row_` 前缀猜测;
578
+ 5. 第二遍写入全部已解析父键,校验新父边无冲突、无自指、无环;
579
+ 6. `copyTreeData()` 返回移除了旧 children 容器的规范平铺数组,直接交给
580
+ `transform: true` 的 VXE;只有提交出口才重建嵌套 `childrenField`。
581
+
582
+ ### 8.4 产品编码复制示例
583
+
584
+ 原数据:
585
+
586
+ ```js
587
+ [
588
+ { id: 100, code: "P001", parentCode: null },
589
+ { id: 101, code: "P002", parentCode: "P001" },
590
+ ]
591
+ ```
592
+
593
+ 采用:
594
+
595
+ ```js
596
+ treeIdentityConfig: {
597
+ physicalIdField: "id",
598
+ rootParentValue: null,
599
+ },
600
+ treeCopyConfig: {
601
+ rowFieldStrategy: "preserve",
602
+ }
603
+ ```
604
+
605
+ 复制结果:
606
+
607
+ ```js
608
+ [
609
+ { id: null, code: "P001", parentCode: null },
610
+ { id: null, code: "P002", parentCode: "P001" },
611
+ ]
612
+ ```
613
+
614
+ 产品编码和父子引用均保持业务含义,只有物理 ID 被清空。
615
+
616
+ ### 8.5 技术树键复制示例
617
+
618
+ 原数据:
619
+
620
+ ```js
621
+ [
622
+ { id: 100, nodeKey: "N001", parentKey: null },
623
+ { id: 101, nodeKey: "N002", parentKey: "N001" },
624
+ ]
625
+ ```
626
+
627
+ 该例明确约定服务端生成并回填技术树键:
628
+
629
+ ```js
630
+ treeIdentityConfig: {
631
+ physicalIdField: "id",
632
+ serverGeneratesRowField: true,
633
+ },
634
+ treeCopyConfig: {
635
+ rowFieldStrategy: "regenerate",
636
+ }
637
+ ```
638
+
639
+ 复制后的编辑态:
640
+
641
+ ```js
642
+ [
643
+ {
644
+ id: null,
645
+ nodeKey: "row_a",
646
+ parentKey: null,
647
+ _X_TREE_TEMP_KEY: "row_a",
648
+ },
649
+ {
650
+ id: null,
651
+ nodeKey: "row_b",
652
+ parentKey: "row_a",
653
+ _X_TREE_TEMP_KEY: "row_b",
654
+ },
655
+ ]
656
+ ```
657
+
658
+ 这里重新生成是合理的,因为 `nodeKey` 是技术身份,不是产品编码。
659
+
660
+ `regenerate` 生成的是前端临时键,提交时会被清空。只有后端能够根据嵌套结构生成
661
+ 正式树键并恢复父子关系时才能使用默认生成器;如果后端要求前端提交正式树键,
662
+ 必须为 `regenerate` 配置永久键生成器,或使用 `custom` 返回
663
+ `temporary: false` 的永久值。
664
+
665
+ ### 8.6 默认 id 树复制示例
666
+
667
+ 原数据:
668
+
669
+ ```js
670
+ [
671
+ { id: 100, f_parent: null },
672
+ { id: 101, f_parent: 100 },
673
+ ]
674
+ ```
675
+
676
+ 第一遍先快照 `100 -> null`、`101 -> 100`,再生成副本:
677
+
678
+ ```js
679
+ [
680
+ {
681
+ id: "row_a",
682
+ f_parent: null,
683
+ _X_TREE_TEMP_KEY: "row_a",
684
+ },
685
+ {
686
+ id: "row_b",
687
+ f_parent: "row_a",
688
+ _X_TREE_TEMP_KEY: "row_b",
689
+ },
690
+ ]
691
+ ```
692
+
693
+ 第二遍父映射读取的是旧快照中的 `100`,不是已经改写的副本。最终提交时两个临时
694
+ `id` 被清空,子节点通过嵌套结构表达其父子关系。
695
+
696
+ ## 9. 整表提交组装
697
+
698
+ 整表提交统一调用:
699
+
700
+ ```js
701
+ buildTreeSubmitData(sources, context)
702
+ ```
703
+
704
+ 不得依赖 VXE 当前是否恰好已生成 `children` 的副作用。算法顺序固定如下:
705
+
706
+ 1. 读取每个 `hasChildField` 节点的懒加载状态,并先执行未加载策略;
707
+ 2. 从平铺、`childrenField`、`mapChildrenField` 遍历当前允许提交的所有 occurrence,
708
+ 每次先记录容器父边;
709
+ 3. 再按对象引用和规范化 `rowField` 去重节点 payload,保留全部 occurrence 边;
710
+ 4. 以规范化 `parentField` 为权威;嵌套边只补全没有父字段的 nested-only 节点;
711
+ 5. 校验 `rowField` 唯一性、根哨兵冲突、多父、自指和有向环;
712
+ 6. 若仍有临时 `rowField` 且 `serverGeneratesRowField: false`,在清洗前阻止提交;
713
+ 7. 在清理临时值之前,根据原始树键快照父子拓扑;
714
+ 8. 克隆节点,后续操作只处理副本;
715
+ 9. 删除副本上的旧 `childrenField` 和 `mapChildrenField`;
716
+ 10. 按已验证的父边重建唯一 `childrenField`;
717
+ 11. 根节点父值规范为 `treeIdentityConfig.rootParentValue`;
718
+ 12. 递归执行 `sanitizeTreeRow()`;
719
+ 13. 返回顶层提交数组。
720
+
721
+ ### 9.1 懒加载完整性
722
+
723
+ “未加载”不等于“已加载且为空”:
724
+
725
+ - `lazy: false`:当前规范快照视为完整,`hasChildField: true` 只作为业务元数据,
726
+ 不触发未加载判断;
727
+ - `lazy: true`:通过 VXE 已加载状态读取适配器 `isTreeNodeLoaded(row)` 判断,
728
+ 不能根据 `children.length === 0` 猜测;
729
+ - `unloadedChildrenStrategy: "reject"`:默认行为,存在未加载后代时阻止整表提交;
730
+ - `loadAll`:递归加载并等待完成,再重新取得一致性快照;
731
+ - `omit`:仅在后端明确约定“缺少 `childrenField` 表示该子树未参与本次更新”时使用;
732
+ 未加载节点必须省略 children 字段,不能写 `children: []`;
733
+ - 已加载且确实为空的节点可以输出 `children: []`,表示已知空集合。
734
+
735
+ `hasChildField` 不能只被解析却不参与算法。复制只允许 `reject` 或 `loadAll`,
736
+ 整表提交的 `omit` 必须经过接口联调确认,防止被后端解释为删除全部后代。
737
+ 运行时上下文必须同时提供 `isTreeNodeLoaded` 和 `loadTreeChildren` 适配器;
738
+ `loadAll` 缺少 loader、任一请求失败或加载后状态仍不完整时统一按 `reject` 结束,
739
+ 不生成部分提交体。
740
+
741
+ 异步边界固定如下:
742
+
743
+ ```text
744
+ 保存/提交 UI 动作
745
+ -> await ensureAllTreeChildrenLoaded(仅 loadAll)
746
+ -> 重新读取 VXE 最新一致性快照
747
+ -> 同步 buildSubmitPayload / buildTreeSubmitData
748
+ -> 发请求
749
+ ```
750
+
751
+ 复制 UI 动作同样先 `await`,再同步调用 `copyTreeData()`。现有
752
+ `getSubData2()`/`getRealFormData()` 保持同步且非阻断:普通字段脚本、确认文案等
753
+ 读取时只返回当前已加载数据,不触发网络,也不因树不完整而抛错。严格的完整性校验
754
+ 只放在新增的显式提交序列化入口 `buildSubmitPayload()` 中;保存动作必须使用该入口,
755
+ 该入口以显式 `mode: "submit"` 调用同步的 `getSubData2()` 和
756
+ `buildTreeSubmitData()`。默认读取模式不执行提交完整性拒绝。不能再把普通
757
+ `getRealFormData()` 的当前快照直接当作完整提交体,也禁止把 Promise 塞进现有
758
+ 同步取值链。
759
+
760
+ ### 9.2 根和孤儿节点
761
+
762
+ - `parentField` 为任一读取兼容根值:顶层节点,并规范输出为 `rootParentValue`;
763
+ - 父键能匹配本次节点集合:挂到匹配父节点下;
764
+ - 父键非空但父节点不在本次集合:
765
+ - 命中 `temporaryKeyRegistry`,或能在全表上下文找到仍带临时标记的父节点时,
766
+ 拒绝提交并要求包含/先保存父节点;
767
+ - `treeSubmitConfig.orphanParentStrategy: "preserve"` 仅在父键来自
768
+ `knownFormalKeyRegistry`,或 `validateExternalParentKey` 明确通过时,才作为
769
+ 顶层输出并保留外部父键;
770
+ - 来源未知且无法确认正式性的父键默认拒绝;
771
+ - `reject` 时阻止提交并报告节点;
772
+ - `treeCopyConfig.orphanParentStrategy` 只控制复制范围之外的父引用,不改变正常
773
+ 整表提交的孤儿规则;
774
+ - 如果后端不支持“顶层携带外部父键”,应先明确并调整接口契约,不能在提交端静默
775
+ 清空父键或丢弃节点。
776
+
777
+ ### 9.3 递归清洗规则
778
+
779
+ 每个节点都执行,而不是只处理顶层:
780
+
781
+ 1. `physicalIdField`:
782
+ - 普通编辑的真实物理 ID 保留;
783
+ - 复制态的原物理 ID 已在复制阶段清空;
784
+ - 当该字段同时也是带标记的临时 `rowField` 时,编辑态可持有新 `row_*`,
785
+ 提交清洗时再置空;
786
+ 2. `rowField`:
787
+ - 值与 `_X_TREE_TEMP_KEY` 相等且 `serverGeneratesRowField: true` 时清空;
788
+ - 值仍为临时键但服务端不负责生成时,必须在清洗前报错,不能提交 `null`;
789
+ - 产品编码等正式值保留;
790
+ - 默认 `id` 兼容历史 `row_*` 前缀;
791
+ 3. `parentField`:
792
+ - 指向本次新增父节点临时键时,在嵌套关系已经表达父子关系后清空;
793
+ - 指向本次集合外、已经确认正式的父节点时保留;
794
+ 4. 删除 `_X_ROW_KEY`、`_X_ROW_CHILD`、`_X_TREE_TEMP_KEY` 及其他 VXE 内部字段;
795
+ 5. 删除 `mapChildrenField`;
796
+ 6. 仅保留重建后的 `childrenField`,并继续递归清洗。
797
+
798
+ 同一业务节点在最终 JSON 中只能出现一次。
799
+
800
+ ### 9.4 提交成功后的身份回填
801
+
802
+ 提交清洗只作用于请求副本,表格原对象仍保留临时键。只要本次请求存在
803
+ `physicalIdField` 为空/临时的新节点,或存在需要服务端生成/改变 `rowField` 的节点,
804
+ 接口成功后必须强制重新查询表格/表单,以服务端正式
805
+ `physicalIdField`、`rowField`、`parentField` 替换整个编辑态。重新加载完成前不开放
806
+ 下一次保存或子行编辑;reload 失败时保留当前临时编辑态、提示用户重试,不能把本次
807
+ 保存标记为完整结束。
808
+
809
+ 本次落地不支持仅靠响应数组顺序或业务字段猜测逐节点映射。自定义保存成功回调也不得
810
+ 跳过 reload;否则再次保存会重复新增,子行会继续被判定为未持久化。未来若要支持
811
+ 无 reload 回填,必须另行设计后端可回显的专用 client token 协议,不能复用已在请求
812
+ 副本中清空的临时 `rowField`。
813
+
814
+ ## 10. 单行保存
815
+
816
+ 单行保存不能继续只调用仅认识字面量 `id` 的通用清洗器。统一流程为:
817
+
818
+ ```text
819
+ 检查父节点是否已经持久化
820
+ -> 校验当前 rowField 是否可提交
821
+ -> 克隆当前行及必要上下文
822
+ -> 同步树键引用
823
+ -> sanitizeTreeRow(mode: "single")
824
+ -> commonDataUtil.handleForm
825
+ -> 发起请求
826
+ -> 合并服务端正式身份并同步所有直接子节点引用
827
+ ```
828
+
829
+ 默认采用“父节点先保存”策略:
830
+
831
+ - `mode: "single"` 的请求对象必须删除 `childrenField` 和 `mapChildrenField`,
832
+ 只序列化当前行;完整表格上下文仅用于关系校验和成功后的引用同步,不能把父行下的
833
+ 未保存子节点一起发到单行接口;
834
+ - 当前行是子节点,且其父节点的 `physicalIdField` 为空或仍为临时状态时,禁止单独
835
+ 保存子节点,并提示先保存父节点;
836
+ - 父对象不在当前单行上下文时,同样先校验父键来源:命中
837
+ `temporaryKeyRegistry` 时拒绝;只有 `knownFormalKeyRegistry` 或
838
+ `validateExternalParentKey` 确认后才保留;来源未知默认拒绝;
839
+ - 不能清空临时 `parentField` 后把子节点当根保存,也不能把 `row_*` 发给后端;
840
+ - 父节点保存成功后,无论 `rowField` 与物理 ID 是否为同一字段,只要服务端返回的
841
+ 正式 `rowField` 与旧临时键不同,都必须调用 `syncTreeKeyReferences()` 更新所有
842
+ 直接子节点;
843
+ - 配置 `serverGeneratesRowField: true` 时,保存响应必须返回正式 `rowField`;
844
+ 缺失时视为保存协议错误,不能清除本地临时标记;
845
+ - 自定义业务 `rowField` 仍是临时值且服务端不生成时,保存前阻止并提示完成业务选择;
846
+ - `rowField === "id"` 时已由配置约束保证 `physicalIdField === "id"`,因此后续
847
+ `commonDataUtil.handleForm` 和请求层对临时 `id` 的处理不会误伤独立业务编码;
848
+ - 原始行不因请求清洗而丢失编辑态数据;
849
+ - 单行保存与整表提交对同一节点使用同一字段清洗规则。
850
+
851
+ 若某个后端确实支持“子行携带未保存父行一起级联保存”,应另建显式批量接口适配,
852
+ 不复用单行保存路径。
853
+
854
+ 整表提交使用 `mode: "tree"`,只有该模式才重建并递归保留 `childrenField`。
855
+
856
+ ## 11. 展开、排序、删除和持久化判断
857
+
858
+ 以下链路必须复用 `resolveTreeFields()`、`isRootParent()` 和
859
+ `treeKeyEquals()`:
860
+
861
+ - 首次自动展开和 `expandAll`;
862
+ - 懒加载参数组装;
863
+ - 上移、下移、同级排序;
864
+ - 删除父节点及收集后代;
865
+ - 按树键定位和激活行;
866
+ - `hasSaveRow`、`hasEditingRow` 等状态判断。
867
+
868
+ 不得使用:
869
+
870
+ ```js
871
+ !row[parentField]
872
+ ids.includes(row[rowField])
873
+ row.id
874
+ ```
875
+
876
+ 来替代统一口径。
877
+
878
+ `tableTreeMixins` 实际被 xform 编辑树表直接混入,不能再视为独立、不相关模块。
879
+ 其中的持久化判断应读取显式 `physicalIdField`;其他写死 `id` 的方法若不属于 xform
880
+ 调用路径,要用调用检索和测试锁定边界,而不是凭目录位置排除。
881
+
882
+ ## 12. 文件级改造清单
883
+
884
+ ### 12.1 新增
885
+
886
+ `src/components/xform/utils/treeTableUtil.js`
887
+
888
+ - 放置字段解析、关系归一、复制、递归收集、递归清洗和提交组装纯函数;
889
+ - 不依赖 Vue 组件实例,确保可直接单测。
890
+
891
+ ### 12.2 修改
892
+
893
+ `src/components/xform/form-render/container-item/data-table-mixin.js`
894
+
895
+ - 合并并校验最终 `treeConfig`;
896
+ - 读取 `treeIdentityConfig`、`treeCopyConfig`、`treeSubmitConfig`;
897
+ - 初始数据、`setValue`、复制插入和懒加载结果入 VXE 前先规范成唯一平铺模型;
898
+ - 新增/编辑/单行保存统一走树工具;
899
+ - 未保存父节点下的子节点禁止单行保存,父保存响应统一回填树键;
900
+ - 自动展开、排序、懒加载、定位逻辑统一键比较;
901
+ - `mapChildren` 显式默认值和 `transform` 约束落地。
902
+
903
+ `src/components/xform/form-render/indexMixin.js`
904
+
905
+ - `handleCopyTreeData` 改为明确区分物理 ID 和 `rowField`;
906
+ - 复制先快照旧键,返回规范平铺副本,不复制/重建旧 children 容器;
907
+ - 新增异步提交编排入口 `buildSubmitPayload()`:先完成 `loadAll`,再同步序列化;
908
+ - `getSubData2` 增加显式 read/submit 上下文;普通读取保持同步非阻断,提交模式调用
909
+ 递归的 `buildTreeSubmitData`;
910
+ - 复制与整表提交不再只处理顶层节点,并执行懒加载完整性策略。
911
+
912
+ `src/components/xform/mixins/defaultHandle.js`
913
+
914
+ - 默认保存不能继续在 validate 回调中同步取得 `getReqFormData()` 后直接请求;
915
+ - 保存流程改为 `await buildSubmitPayload()`,取得严格提交快照后再调用接口;
916
+ - 保存成功后按 9.4 的触发条件 `await reload`,完成前不结束保存状态;
917
+ - 自定义保存入口必须遵守同一异步提交与 reload 契约;
918
+ - `getReqFormData()`、`getRealFormData()` 保留为同步只读 API,不承担提交完整性保证。
919
+
920
+ `src/mixins/tableTree/index.js`
921
+
922
+ - xform 实际使用的持久化/编辑态判断改为读取 `physicalIdField`;
923
+ - 不在 xform 调用路径中的方法只做边界核实,不顺带扩大重构范围。
924
+
925
+ ### 12.3 明确不修改
926
+
927
+ `src/resources/js/base/common.js`
928
+
929
+ 这是跨业务通用清洗器,不应让它理解 xform 树表的动态 `rowField` 和临时标记。
930
+ 树表专属清洗应在调用通用清洗器之前完成。字面量 `id` 保留为物理 ID 的强约束,
931
+ 保证现有通用清洗和请求层的二次临时 ID 处理仍然安全。
932
+
933
+ ## 13. 测试方案
934
+
935
+ ### 13.1 工具函数单测
936
+
937
+ 至少覆盖:
938
+
939
+ 1. 五种根父值;
940
+ 2. `0`/`"0"` 作为真实树键时被拒绝;
941
+ 3. number/string 父子键归一;
942
+ 4. 归一后键冲突;
943
+ 5. 平铺数据建树;
944
+ 6. 仅 `children` 的嵌套数据;
945
+ 7. 仅 `mapChildren` 的懒加载数据;
946
+ 8. 同一节点同时出现在两种 children 中只收集一次;
947
+ 9. 孤儿节点保留外部父键;
948
+ 10. 新增节点临时标记;
949
+ 11. 正式键回填并同步子节点;
950
+ 12. 合法业务值 `row_001` 不被清理;
951
+ 13. 默认 `id` 历史临时值兼容;
952
+ 14. 复制时清空物理 ID;
953
+ 15. `preserve` 保留产品编码;
954
+ 16. `regenerate` 重建技术键和父映射;
955
+ 17. `custom` 返回正式值;
956
+ 18. `custom` 返回临时值;
957
+ 19. 递归清洗所有层级;
958
+ 20. 内部字段全部移除;
959
+ 21. 默认 `rowField === physicalIdField === "id"` 的三层复制先快照再映射;
960
+ 22. 同一对象引用去重;
961
+ 23. 不同对象实例、同一稳定身份且内容一致时合并;
962
+ 24. 不同对象实例、同一稳定身份但内容冲突时失败;
963
+ 25. `parentField` 与嵌套边冲突、多父、自指和多节点环;
964
+ 26. 未加载子树与已加载空子树的区别;
965
+ 27. 临时业务 `rowField` 且服务端不生成时拒绝提交;
966
+ 28. `rootParentValue` 为 `null`、`0`、`"0"` 的规范输出;
967
+ 29. 默认与自定义 `mapChildren` 解析;
968
+ 30. 复制和提交的孤儿策略互不串用;
969
+ 31. `rowField === physicalIdField` 时显式 `preserve` 和永久键生成被拒绝;
970
+ 32. 复制生成键在复制集合及目标表中的碰撞;
971
+ 33. 同一对象 occurrence 挂在两个父节点下或挂到自身时仍能检出;
972
+ 34. `preserve` 遇到源临时树键时拒绝;
973
+ 35. 外部父键分别命中临时 registry、正式 registry 和未知来源;
974
+ 36. 非法 `rootParentValue` 与所有字段碰撞组合;
975
+ 37. 同步生成器返回 Promise 时拒绝;
976
+ 38. 外部父键同步校验器返回 Promise 时拒绝;
977
+ 39. 父到子拓扑生成中,子组合键正确使用父副本的 `newParentKey`。
978
+
979
+ ### 13.2 组件/集成测试
980
+
981
+ 至少覆盖:
982
+
983
+ - 宿主 `dataTableOption.config.treeConfig` 局部覆写后字段不丢失;
984
+ - 表单脚本覆写后的最终配置校验;
985
+ - nested-only 输入先规范平铺,再进入真实 VXE,全部后代仍存在;
986
+ - `transform: false` 被拦截并恢复,且节点数量和父子结构正确;
987
+ - 新增根、新增子、编辑树键;
988
+ - 已持久化物理主键编辑被拒绝;
989
+ - 已持久化业务树键不能走普通单行保存;
990
+ - `transactional` 树键变更覆盖后端成功、失败回滚和未加载子节点;
991
+ - 产品选择器把临时键替换为产品编码;
992
+ - 自定义 `rowField` 单行保存;
993
+ - 父行已有 children 时,单行请求体仍只包含当前父行;
994
+ - 新父节点未保存时,子节点单行保存被阻止;
995
+ - 父节点保存响应回填正式树键后,所有直接子节点父引用被同步;
996
+ - 产品编码树复制;
997
+ - 技术键树复制;
998
+ - 默认 `rowField === physicalIdField === "id"` 的多层树复制;
999
+ - 同字段身份配置的非法 `preserve`/永久键策略被拦截;
1000
+ - 复制生成器碰撞时整次失败且表格数据不变;
1001
+ - 同表复制业务键冲突提示;
1002
+ - 未加载子树复制的 `reject` 与 `loadAll`;
1003
+ - 未加载节点提交的 `reject`、`loadAll`,以及经联调启用的 `omit`;
1004
+ - `lazy: false` 不因 `hasChild: true` 误判未加载;
1005
+ - `lazy: true` 只读取 VXE 加载状态,缺少 loader/加载失败不生成部分数据;
1006
+ - 远程号段先异步预取、纯复制阶段同步分配;
1007
+ - 默认和自定义 `mapChildren`;
1008
+ - number/string 数据分别通过初始加载、`setValue`、懒加载进入表格;
1009
+ - 每个入口都断言 VXE 根节点数量、每个逻辑节点只出现一次、最终请求体只出现一次;
1010
+ - 首次自动展开的 `"0"` 根值;
1011
+ - 删除、上下移、排序按统一键工作;
1012
+ - 完整提交与单行保存清洗结果一致;
1013
+ - 新增/复制节点保存成功后必须等待 reload,reload 失败不得开放下一次保存;
1014
+ - 普通 `getRealFormData()` 在懒树未加载时仍同步返回当前快照且不抛提交校验错误;
1015
+ - 表格编辑态对象在提交前后深比较不变。
1016
+
1017
+ ### 13.3 回归测试
1018
+
1019
+ - 默认 `rowField: "id"` 的既有树表;
1020
+ - 非树普通表新增、编辑、复制、提交;
1021
+ - 查询表、分页表、懒加载表;
1022
+ - 导出仍使用后端物理 ID,不随 `rowField` 改动;
1023
+ - 现有 Jest、ESLint 和构建检查。
1024
+
1025
+ ## 14. 验收样例
1026
+
1027
+ ### 14.1 产品编码树复制
1028
+
1029
+ 输入:
1030
+
1031
+ ```js
1032
+ dataTableOption: {
1033
+ config: {
1034
+ treeConfig: {
1035
+ rowField: "code",
1036
+ parentField: "parentCode",
1037
+ children: "children",
1038
+ mapChildren: "_X_ROW_CHILD",
1039
+ transform: true,
1040
+ },
1041
+ },
1042
+ treeIdentityConfig: {
1043
+ physicalIdField: "id",
1044
+ rootParentValue: null,
1045
+ },
1046
+ treeCopyConfig: {
1047
+ rowFieldStrategy: "preserve",
1048
+ },
1049
+ }
1050
+ ```
1051
+
1052
+ 最终提交:
1053
+
1054
+ ```js
1055
+ [
1056
+ {
1057
+ id: null,
1058
+ code: "P001",
1059
+ parentCode: null,
1060
+ children: [
1061
+ {
1062
+ id: null,
1063
+ code: "P002",
1064
+ parentCode: "P001",
1065
+ },
1066
+ ],
1067
+ },
1068
+ ]
1069
+ ```
1070
+
1071
+ 验收点:`code` 未改变,原物理 ID 未提交,无 `_X_*` 字段。
1072
+
1073
+ ### 14.2 技术树键复制
1074
+
1075
+ 前置配置:
1076
+
1077
+ ```js
1078
+ treeIdentityConfig: {
1079
+ physicalIdField: "id",
1080
+ serverGeneratesRowField: true,
1081
+ }
1082
+ ```
1083
+
1084
+ 编辑态允许:
1085
+
1086
+ ```js
1087
+ {
1088
+ id: null,
1089
+ nodeKey: "row_a",
1090
+ _X_TREE_TEMP_KEY: "row_a",
1091
+ }
1092
+ ```
1093
+
1094
+ 提交态:
1095
+
1096
+ ```js
1097
+ {
1098
+ id: null,
1099
+ nodeKey: null,
1100
+ }
1101
+ ```
1102
+
1103
+ 子节点已经嵌套在父节点下时,其指向 `row_a` 的临时父键也应清空。
1104
+
1105
+ ### 14.3 新节点选择产品
1106
+
1107
+ 过程:
1108
+
1109
+ ```text
1110
+ 临时 code = row_a
1111
+ -> 用户选择 P001
1112
+ -> code = P001
1113
+ -> 所有直接子节点 parentCode: row_a -> P001
1114
+ -> 删除 _X_TREE_TEMP_KEY
1115
+ ```
1116
+
1117
+ 验收点:最终提交保留 `P001`,不会因前缀规则被清掉。
1118
+
1119
+ ### 14.4 默认 id 树复制
1120
+
1121
+ 输入父子键为 `id: 100`、`id: 101 / f_parent: 100`。复制后必须先得到两个不同的
1122
+ 临时 `id`,子节点指向复制后父节点的临时 `id`;提交后两个临时 ID 均清空,子节点
1123
+ 只嵌套在复制后的父节点下一次。
1124
+
1125
+ ### 14.5 未保存父节点下的单行保存
1126
+
1127
+ 父节点物理 ID 仍为空时,单独保存其子节点必须在前端被阻止,不发送请求。父节点保存
1128
+ 成功并返回正式 `rowField` 后,先同步子节点 `parentField`,再允许保存子节点。
1129
+
1130
+ ### 14.6 懒加载完整性
1131
+
1132
+ 节点 `hasChild: true` 且后代未加载时:
1133
+
1134
+ - 默认复制和整表提交均被阻止;
1135
+ - `loadAll` 必须等完整后代加载结束再重取快照;
1136
+ - 只有明确启用并联调过 `omit` 的提交才可继续,且请求中不得出现该节点的
1137
+ `children: []`。
1138
+
1139
+ ### 14.7 已持久化树键变更
1140
+
1141
+ 已落库父节点的物理主键编辑必须被拒绝。独立业务 `rowField` 默认同样不可直接编辑;
1142
+ 启用 `transactional` 后,验收请求必须由专用接口一次更新父键和全部子引用,模拟
1143
+ 接口失败时前端与后端都保持旧关系。
1144
+
1145
+ ## 15. 已审查问题与落地点
1146
+
1147
+ | 已发现问题 | 最终落地点 |
1148
+ |---|---|
1149
+ | 自定义 `rowField` 单行保存泄漏 `row_*` | `sanitizeTreeRow` 同时服务单行与整表 |
1150
+ | `getSubData2` 只清理顶层 | `collectTreeNodes` + 递归组装/清洗 |
1151
+ | 复制自定义 `rowField` 时保留旧物理 `id` | `physicalIdField` 独立并在复制第一遍清空 |
1152
+ | 产品编码被改成新 `row_*` | 默认 `preserve`,禁止混同物理 ID |
1153
+ | rowField 与物理 ID 同字段却显式 preserve/永久生成 | 配置守卫,仅允许服务端生成的带标记临时键 |
1154
+ | 技术树键复制后父引用仍指向旧树 | 两遍复制和旧键到新键映射 |
1155
+ | 只靠 `row_` 前缀判断临时值 | `_X_TREE_TEMP_KEY` 精确标记 |
1156
+ | 正式树键变化后子节点断链 | `changeTreeRowField` 同步引用 |
1157
+ | 已持久化树键只改前端/父行导致后端断链 | 默认禁止;特殊场景走后端事务级联接口 |
1158
+ | `transform: false` 时子节点丢失 | 合并后强制校验并恢复为 `true` |
1159
+ | nested-only 数据直接进入 transform 后代丢失 | 入 VXE 前统一规范平铺 |
1160
+ | number/string 混用导致 VXE 与提交口径不同 | 数据入表前关系类型归一 |
1161
+ | `_X_ROW_CHILD` 和不同实例导致重复 | 对象引用 + 稳定身份去重,冲突失败 |
1162
+ | 父字段、嵌套边冲突或形成环 | 父字段为权威并执行多父/自指/环校验 |
1163
+ | 默认 id 复制先清 ID 后映射断链 | 清洗前快照旧 rowField/parentField |
1164
+ | 未加载子树被当成空树 | `hasChild` 加载态和 reject/loadAll/omit 协议 |
1165
+ | 未保存父节点下的子行单独保存 | 默认阻止,父保存回填正式键后再开放 |
1166
+ | 临时业务键被清成 null | `serverGeneratesRowField` 契约与提交前阻断 |
1167
+ | `tableTreeMixins` 写死 `row.id` | 纳入 xform 调用边界与物理 ID 配置 |
1168
+
1169
+ ## 16. 实施顺序
1170
+
1171
+ ### 阶段一:纯函数和测试先行
1172
+
1173
+ 1. 建立 `treeTableUtil.js`;
1174
+ 2. 完成根值、键归一、稳定身份去重、图校验、规范平铺、复制和递归清洗单测;
1175
+ 3. 用产品编码、默认 id 和独立技术树键样例锁定策略差异;
1176
+ 4. 用未加载/已加载空子树锁定懒加载语义。
1177
+
1178
+ ### 阶段二:优先修复数据安全出口
1179
+
1180
+ 1. 复制时清空物理 ID;
1181
+ 2. 默认 id 复制先快照再映射;
1182
+ 3. 单行保存接入专属清洗和“父节点先保存”守卫;
1183
+ 4. `getSubData2` 接入递归提交组装及加载完整性校验;
1184
+ 5. 防止临时键、旧 ID 和内部字段进入请求。
1185
+
1186
+ ### 阶段三:运行时链路收敛
1187
+
1188
+ 1. 所有入表入口接入规范平铺、类型归一和图校验;
1189
+ 2. 新增、树键编辑和保存响应回填接入统一入口;
1190
+ 3. 首次展开、懒加载、排序、删除、定位统一键比较;
1191
+ 4. `mapChildren` 和 `transform` 配置守卫;
1192
+ 5. 核实并修复 xform 实际调用的 `tableTreeMixins` 方法。
1193
+
1194
+ ### 阶段四:回归与发布
1195
+
1196
+ 1. 执行单测、组件测试、ESLint 和构建;
1197
+ 2. 对默认 `id` 树表和自定义业务键树表各做一次接口联调;
1198
+ 3. 检查复制、新增、单行保存、整表提交请求体;
1199
+ 4. 确认无旧物理 ID、无临时键、无 `_X_*` 字段后再发布。
1200
+
1201
+ ## 17. 完成标准
1202
+
1203
+ 全部满足后才可标记为落地完成:
1204
+
1205
+ - [ ] `rowField` 与物理 ID 在命名、配置和实现中已拆分;
1206
+ - [ ] 复制产品编码树时编码保持不变;
1207
+ - [ ] 复制技术键树时整棵子树完成新键映射;
1208
+ - [ ] 所有复制节点的旧物理 ID 已清空;
1209
+ - [ ] 默认 id 多层树复制使用旧键快照且父映射正确;
1210
+ - [ ] `rowField === physicalIdField` 不会保留或写回任何旧/永久物理 ID;
1211
+ - [ ] 所有复制新树键在复制集合和目标表内唯一;
1212
+ - [ ] 新增节点使用显式临时标记;
1213
+ - [ ] 正式树键回填会同步直接子节点父引用;
1214
+ - [ ] 已持久化物理主键不可编辑,业务树键不会通过普通单行保存半更新;
1215
+ - [ ] 未保存父节点下的子节点不会走单行保存请求;
1216
+ - [ ] 单行保存不会携带当前行的 children/mapChildren 子树;
1217
+ - [ ] 单行保存和整表提交均递归清洗;
1218
+ - [ ] 平铺、嵌套、懒加载数据无丢失、无重复;
1219
+ - [ ] 未加载子树不会被当作已加载空树;
1220
+ - [ ] `lazy: false/true` 使用正确完整性口径,加载失败不产生部分请求;
1221
+ - [ ] 不同实例重复、父边冲突、自指和环均有明确失败行为;
1222
+ - [ ] 同一对象的每个 occurrence 父边都参与图校验;
1223
+ - [ ] 外部父键只有经正式 registry/validator 确认后才能提交;
1224
+ - [ ] number/string 父子关系在进入 VXE 前已归一;
1225
+ - [ ] 默认根输出仍为现有协议 `0`,特殊接口通过配置显式修改;
1226
+ - [ ] 非法根值、字段名碰撞和异步键生成器会在运行前被拦截;
1227
+ - [ ] 默认和自定义 `mapChildren` 均从最终有效配置解析;
1228
+ - [ ] `transform: false` 不会进入运行态;
1229
+ - [ ] VXE 内部字段和临时标记不进入请求;
1230
+ - [ ] 提交组装不修改表格原对象;
1231
+ - [ ] 新身份落库后强制 reload,完成前不会再次保存;
1232
+ - [ ] 普通同步取值 API 不触发加载,也不执行提交完整性拒绝;
1233
+ - [ ] 默认 `rowField: "id"` 的既有功能回归通过;
1234
+ - [ ] 新增测试覆盖本文测试矩阵。
1235
+
1236
+ ---
1237
+
1238
+ <details>
1239
+ <summary>附录:此前实现记录(已被上文方案取代,仅保留审查追溯)</summary>
1240
+
1241
+ 以下内容记录了第一版实现及当时的判断,其中“`rowField` 等同物理 ID”、
1242
+ “复制一律重建 `rowField`”以及“`tableTreeMixins` 不在 xform 范围”等结论均不再作为
1243
+ 实现依据。
1244
+
1245
+ ## 一、背景与问题定性
1246
+
1247
+ ### 1.1 起因
1248
+
1249
+ `getSubData2()` 提交树表数据时,根节点过滤条件为:
1250
+
1251
+ ```js
1252
+ item[parentField] === 0 || item[parentField] === null
1253
+ ```
1254
+
1255
+ 存在两个缺陷:
1256
+
1257
+ 1. **口径过窄**:后端回来的父字段常见 `""`、`"0"`,这些根行连同整棵子树被过滤丢失;
1258
+ 2. **判定时机错误**:过滤前的清洗会把 `"row_"` 开头的临时父 id 置 `null`,
1259
+ 新增子行(父行也是新增、id 为 `row_xxx`)因此被误判为根节点——既作为顶层提交,
1260
+ 又嵌在父行 `f_children` 里,提交数据重复、层级错乱。
1261
+
1262
+ ### 1.2 根因(rowField 三链分叉)
1263
+
1264
+ 排查发现问题不止提交端。整个树表存在**三条并存的"树主键"取值链**,
1265
+ 仅在默认值 `id` 上巧合重合:
1266
+
1267
+ | 链 | 取值方式 | 来源 |
1268
+ |---|---|---|
1269
+ | A | vxe 内部 `treeOpts.rowField` | `Object.assign({}, 全局默认, treeConfig prop)`,全局默认 `'id'`;transform 建树(xe-utils `toArrayTree`)以它为 key |
1270
+ | B | 业务代码 `$grid.treeConfig.rowField \|\| "id"` | 读原样 prop;改造前字面量未声明 rowField,恒 undefined → 落到 `"id"` |
1271
+ | C | 写死字面量 `.id` | 新增行临时 id、父子挂接 `parent?.id`、行定位、自动展开、回显排序等十余处 |
1272
+
1273
+ **触发面**(任一即分叉):
1274
+
1275
+ - 源码给 treeConfig 字面量加 rowField;
1276
+ - 宿主页面传 `dataTableOption.config.treeConfig`(改造前为**整对象替换**,
1277
+ 漏写任何键都会连 rowField/parentField/children 一起丢掉)——运行时可达,无需改 xform 源码。
1278
+
1279
+ 分叉后果:新增行 key 为 undefined 全部挤进 `treeMap[undefined]` 层级全乱、
1280
+ 新增子节点全部变根、`row_` 临时 id 泄漏提交、行定位/自动展开/回显排序失效。
1281
+
1282
+ ### 1.3 rowField 的语义
1283
+
1284
+ `rowField` 是扁平树数据里 **parentField 外键所引用的那一列的列名**。
1285
+ `toArrayTree` 按 `treeMap[row[parentField]].push(row)` 挂树、
1286
+ "父值不在全表 rowField 值集合中"判根。本项目约定 `f_parent` 存父行的 `id` 值。
1287
+
1288
+ 三个易混标识的分工:
1289
+
1290
+ - `rowField`(=id)——业务主键,父子关系锚点,提交给后端;
1291
+ - `_X_ROW_KEY`——vxe 内部行 key,仅表格实例内定位(展开恢复、getRowById),不参与建树;
1292
+ - `f_children` / `_X_ROW_CHILD`——建树产物(children / mapChildren),不是数据源。
1293
+
1294
+ ## 二、落地内容
1295
+
1296
+ 决策:**rowField 保持可配置,treeConfig 为唯一事实源**(方案 b;"全链写死 id" 被否)。
1297
+ 现状 rowField 仍为 `"id"`,本次改造语义零变化,收敛的是"配置变化时链条不再分叉"。
1298
+
1299
+ ### 2.1 `form-render/container-item/data-table-mixin.js`
1300
+
1301
+ **① treeConfig 显式声明 rowField(`buildTableOption`,treeConfig 字面量)**
1302
+
1303
+ ```js
1304
+ treeConfig = {
1305
+ lazy: false,
1306
+ rowField: "id", // ← 唯一声明点,此前隐式依赖 vxe 全局默认
1307
+ children: "f_children",
1308
+ hasChild: "f_has_child",
1309
+ parentField: "f_parent",
1310
+ transform: true,
1311
+ ...
1312
+ }
1313
+ ```
1314
+
1315
+ **② 新增统一读取口 `getTreeFields($grid)`**(`getGridTable` 旁)
1316
+
1317
+ ```js
1318
+ getTreeFields($grid) → { idField, parentField, childrenField, hasChildField }
1319
+ ```
1320
+
1321
+ - `idField` 兜底 `"id"`(与 vxe 全局默认一致);
1322
+ - 其余键**不设兜底**:保持调用方原有空值守卫语义
1323
+ (非树表 treeConfig 缺失时,`addTreeRows` 的 `if (parentField)` 不应凭空写入 `f_parent`)。
1324
+
1325
+ **③ 链 C 写死点全部改走配置**(12 处调用点)
1326
+
1327
+ | 场景 | 方法 | 改造 |
1328
+ |---|---|---|
1329
+ | 新增行临时 id | `addTreeRow` / `addTreeRows` / `addEditRow` | `newRow.id = "row_..."` → `newRow[idField] = ...` |
1330
+ | 父子挂接 | 同上三处 | `parent?.id` → `parent?.[idField]` |
1331
+ | 新增后激活 | `addTreeRow` 两处调用 + `setActiveRowById` 内部比较 | 按 `idField` 传参与查找 |
1332
+ | 回显父子排序 | `handleTreeData` | nodeMap 构建与 `addChildNodes` 递归入口按 `idField` |
1333
+ | 首载自动展开 | proxyConfig query 回调 | `expandIds.includes(item[idField])` 两处 |
1334
+ | 懒加载参数 | `loadMethod` | `[parentField]: row[idField]` |
1335
+
1336
+ **④ 顺手修复的现行 bug:treeNodeParam**
1337
+
1338
+ 原代码读不存在的 `widget.options.parentField`(widgetsConfig 从未定义该选项),
1339
+ 生成 `{undefined: id}` 脏参数。改为从 treeConfig 字面量取 parentField/rowField,
1340
+ 并移到 treeConfig 声明之后。
1341
+ 注:该参数仅在 `treeNodeUrl` 路径(`components/table/index.js`)被消费,
1342
+ xform 树表不走此路径(treeNodeUrl 为注释状态),修复属于纠正死代码语义。
1343
+
1344
+ **⑤ 宿主覆写通道改深合并**
1345
+
1346
+ ```js
1347
+ let hostTableConfig = dataTableConfig.config || {};
1348
+ if (treeConfig && hostTableConfig.treeConfig) {
1349
+ hostTableConfig = {
1350
+ ...hostTableConfig,
1351
+ treeConfig: { ...treeConfig, ...hostTableConfig.treeConfig },
1352
+ };
1353
+ }
1354
+ ```
1355
+
1356
+ - 宿主经 `dataTableOption.config.treeConfig` 只改单键(如 expandAll)不再冲掉其余键;
1357
+ - 新建对象合并,不改宿主经 `$attrs` 传入的原对象;
1358
+ - 非树表宿主传 treeConfig 原样透传,行为不变;
1359
+ - 与表单脚本通道(`extendDeeply(tableOption, tableConfig)`,本身即深合并)语义拉平。
1360
+
1361
+ **⑥ 既有 5 处 `rowField || "id"` 统一走 helper**
1362
+
1363
+ `collectDescendantKeys`、`moveUpRow`、`moveDownRow`、`openSortRowDialog`、`confirmTreeMoveDialog`。
1364
+
1365
+ ### 2.2 `form-render/indexMixin.js` — `getSubData2` 提交端修复
1366
+
1367
+ 树表分支重写(此前轮次落地,与本轮共同构成完整链路):
1368
+
1369
+ 1. `idField = $grid.treeConfig.rowField || "id"`,判根与 vxe 建树同源;
1370
+ 2. **判根先于清洗**:先按原始父子关系算 `isRootFlags`,再清临时 id,
1371
+ 杜绝临时父 id 被清后误判为根;
1372
+ 3. 判根口径与 `toArrayTree` 一致:父值为空(`null/undefined/""/0/"0"`)视为根;
1373
+ 父值非空但父行不在本表数据(过滤/查询后的孤儿行,如 `f_parent=10086` 而
1374
+ 10086 未被查出)**也收进顶层数组且保留 parentField 原值**,
1375
+ 由后端据此挂回既有父节点——不丢数据、不篡改层级;
1376
+ id 比较统一 `String()` 归一防类型不匹配;
1377
+ 4. 临时 id 双清:`clearTempValue` 对 `idField`、字面量 `id`(两者不同才多清一次)、
1378
+ `parentField` 各清一遍。原因:临时 id 有两个写入方——`addTreeRow/addTreeRows`
1379
+ 写 `row.id`,`handleCopyTreeData` 写 `row[rowField]`,提交出口把两条来源都兜住。
1380
+
1381
+ **依赖的后端契约**:顶层数组允许出现 parentField 非空的行(孤儿行),
1382
+ 应按 parentField 挂接既有节点而非一律当根写入。若后端为"顶层即根"实现,需后端配合。
1383
+
1384
+ ## 三、明确不动的部分
1385
+
1386
+ | 项 | 原因 |
1387
+ |---|---|
1388
+ | 导出勾选 ids(`item.id`,约 2926 行附近) | 按决策保持——导出接口收物理 id,不随 rowField 走 |
1389
+ | `mixins/tableTree/`(a-link 非编辑树表生态) | 独立体系(parentField 为 `parent`),不在 xform 范围 |
1390
+ | `handleCopyTreeData`(indexMixin) | 本就走 `rowField \|\| "id"`,与收敛后链路一致 |
1391
+
1392
+ ## 四、验证结果
1393
+
1394
+ - ESLint:`data-table-mixin.js` 56 条 = 改前基线(全为存量 operator-linebreak),零新增;
1395
+ `indexMixin.js` 由 178 → 174(helper 替换掉 4 条历史风格错误);
1396
+ - Jest:8 套 99 例全过(现有用例不覆盖树表链路,属回归性验证);
1397
+ - Babel parse OK;同作用域无变量重复声明;
1398
+ - `setActiveRowById` 无 mixin 之外调用方;`loadMethod` 里 `tableConfig?.treeNodeParam`
1399
+ 读的是表单脚本配置(与被搬动的局部变量无关),时序与引用均验证通过。
1400
+
1401
+ ## 五、后续约定(重要)
1402
+
1403
+ 1. **树表父子关联代码一律经 `getTreeFields($grid)` 取列名,禁止写死 `id`/`f_parent`**——
1404
+ 写死会在配置变化时与 vxe 建树分叉(treeConfig 字面量处有注释锚点);
1405
+ 2. **真要把 rowField 配成非 `id` 列,前端已就绪但必须后端同步**:
1406
+ 主键列、`row_` 前缀新行识别落点、父子挂接列的接口契约都会变,
1407
+ 前端单方面改配置会把错误转移到接口层;
1408
+ 3. 宿主/脚本覆写 treeConfig 均为深合并,只写想改的键即可。
1409
+
1410
+ ## 六、遗留敞口(未处理,单独排期)
1411
+
1412
+ | # | 位置 | 问题 |
1413
+ |---|---|---|
1414
+ | 1 | `indexMixin.js` `treeSubTables`(复制单据) | 默认 `parent_id` ≠ 表格 `f_parent`,漏配时复制树层级指向原单节点 |
1415
+ | 2 | `moveUpRow`/`moveDownRow`/`openSortRowDialog` 同级过滤 | `===` 无 String 归一,number/string 混用会漏匹配 |
1416
+ | 3 | `toArrayTree` 副作用 | 子树同时挂 `f_children` + `_X_ROW_CHILD`(mapChildren 全局默认)在原始行上,提交体积随深度翻倍,需评估提交前是否剔除 `_X_ROW_CHILD` |
1417
+ | 4 | `treeNodeParam` 闭包 | 读字面量 treeConfig 而非运行时合并后的 `$grid.treeConfig`;仅 treeNodeUrl 路径消费(xform 未用),暂无影响 |
1418
+ | 5 | `f_wbs`/`f_has_child` 等 `f_` 前缀约定 | 散落写死,改 parentField 命名需连带梳理 |
1419
+
1420
+ ## 七、分支同步状态
1421
+
1422
+ | 分支 | getSubData2 修复 | data-table-mixin 收敛 |
1423
+ |---|---|---|
1424
+ | corejs(本仓库) | ✅ | ✅ |
1425
+ | `sf-cloud-web-vue-tw@haier_publish_dev` | ✅(同步时移除了原树表分支内一行 `debugger` 调试遗留) | ❌ 按指示暂缓,待通知后同步 |
1426
+
1427
+ </details>