cloud-web-corejs 1.1.0-dev.6 → 1.1.0-dev.61

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 (499) hide show
  1. package/README.md +38 -0
  2. package/bin/core-resources.js +16 -0
  3. package/bin/create-child-app.js +34 -0
  4. package/docs/child-app/README.md +95 -0
  5. package/docs/child-app/activiti-resources.md +63 -0
  6. package/docs/child-app/generate-prompt.md +55 -0
  7. package/docs/child-app/luckysheet-resources.md +80 -0
  8. package/docs/child-app/public-resources-plan.md +288 -0
  9. package/docs/child-app/resources-implementation.md +101 -0
  10. package/docs/child-app/tinymce-resources.md +88 -0
  11. package/docs/child-app/validation.md +34 -0
  12. package/docs/qiankun/346/216/245/345/205/245/345/215/217/350/256/256.md +298 -0
  13. package/docs/qiankun/350/257/246/346/203/205/346/211/277/350/275/275/345/255/220/345/272/224/347/224/250/345/257/271/346/216/245/346/270/205/345/215/225.md +111 -0
  14. package/package.json +29 -4
  15. package/resource-tools/index.js +126 -0
  16. package/src/app-bootstrap.js +531 -0
  17. package/src/app-bootstrap.sync.js +502 -0
  18. package/src/boot-assets.legacy.js +13 -0
  19. package/src/boot-assets.next.js +7 -0
  20. package/src/components/Qrcode/fileParse.vue +11 -0
  21. package/src/components/Tinymce/dynamicLoadScript.js +51 -59
  22. package/src/components/Tinymce/index.vue +382 -336
  23. package/src/components/Tinymce/mce-chrome.scss +150 -0
  24. package/src/components/VabUpload/image-viewer.vue +18 -10
  25. package/src/components/VabUpload/index.js +11 -4
  26. package/src/components/VabUpload/index.vue +1 -1
  27. package/src/components/VabUpload/mixins/fileLibraryDialog.js +2 -0
  28. package/src/components/VabUpload/mixins.js +72 -40
  29. package/src/components/VabUpload/partUploadConfig.js +95 -0
  30. package/src/components/VabUpload/privateProfileDialogMixins.js +2 -0
  31. package/src/components/VabUpload/style.scss +282 -0
  32. package/src/components/VabUpload/view.vue +19 -18
  33. package/src/components/baseArea/index.vue +2 -2
  34. package/src/components/baseInputExport/mixins.js +1 -6
  35. package/src/components/bizTab/BizTabListPage.vue +66 -33
  36. package/src/components/bizTab/README.md +3 -1
  37. package/src/components/bizTab/bizBillDetailMixin.js +2 -0
  38. package/src/components/code-editor/ace-chrome.scss +17 -0
  39. package/src/components/code-editor/index.vue +361 -340
  40. package/src/components/errorMsg/index.vue +142 -13
  41. package/src/components/errorMsg/mixins.js +53 -0
  42. package/src/components/excelExport/conditionExportConfig.js +112 -0
  43. package/src/components/excelExport/exportColumnMemory.js +118 -0
  44. package/src/components/excelExport/exportFieldDialog.vue +50 -38
  45. package/src/components/excelExport/exportType.js +8 -0
  46. package/src/components/excelExport/index.js +30 -13
  47. package/src/components/excelExport/index.vue +7 -1
  48. package/src/components/excelExport/mixins.js +782 -293
  49. package/src/components/excelImport/index.vue +156 -156
  50. package/src/components/excelImport/mixins.js +888 -834
  51. package/src/components/fileLibrary/mixins/indexMixins.js +2 -0
  52. package/src/components/fileLibrary/style.scss +579 -0
  53. package/src/components/formDialog/index.vue +11 -8
  54. package/src/components/hiprint/style.scss +188 -0
  55. package/src/components/hiprint/view/json-view.vue +4 -4
  56. package/src/components/jdPrint/mixins.js +2 -0
  57. package/src/components/jsonImport/index.vue +1 -1
  58. package/src/components/jsonImport/mixins.js +6 -10
  59. package/src/components/langImport/index.vue +1 -1
  60. package/src/components/langImport/mixins.js +6 -10
  61. package/src/components/luckysheet/loadResources.js +64 -0
  62. package/src/components/luckysheet/view.vue +239 -210
  63. package/src/components/mobile/buttonGroup/index.vue +1 -1
  64. package/src/components/mobile/wf/addTaskUserdialog.vue +100 -80
  65. package/src/components/mobile/wf/content.vue +1734 -1662
  66. package/src/components/mobile/wf/deleteTaskUserDialog.vue +73 -54
  67. package/src/components/mobile/wf/selectUserDialog.vue +118 -0
  68. package/src/components/mobile/wf/setCandidateDialog.vue +69 -48
  69. package/src/components/mobile/wf/urgingDialog.vue +75 -52
  70. package/src/components/mobile/wf/wfModifyDialog.vue +4 -0
  71. package/src/components/obsUpload/index.js +4 -1
  72. package/src/components/obsUpload/index.vue +1 -1
  73. package/src/components/obsUpload/mixins.js +45 -15
  74. package/src/components/onlineTalk/index.vue +4 -4
  75. package/src/components/onlineTalk/mixins.js +21 -7
  76. package/src/components/table/index.js +96 -81
  77. package/src/components/table/plugins/cell-area/index.js +10 -3
  78. package/src/components/table/style.scss +1399 -0
  79. package/src/components/table/vxeFilter/mixin.js +28 -18
  80. package/src/components/wf/content.vue +3 -2
  81. package/src/components/wf/content2.vue +1 -1
  82. package/src/components/wf/style.scss +265 -0
  83. package/src/components/wf/wf.js +7 -0
  84. package/src/components/wf/wfActionItems.js +3 -0
  85. package/src/components/wf/wfStartDialog.vue +1 -0
  86. package/src/components/wf/wfTransferEnabled.js +54 -0
  87. package/src/components/wf/wfUtil.js +47 -29
  88. package/src/components/wf/wfVisibility.js +6 -0
  89. 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" +64 -57
  90. package/src/components/xform/docs/2026-08 xform H5 P0 /345/256/236/347/216/260/350/247/204/346/240/274.md" +1 -1
  91. package/src/components/xform/docs/2026-08 xform /347/247/273/345/212/250/347/253/257/345/270/203/345/261/200/345/257/271/351/275/220 bill_setting /346/226/271/346/241/210.md" +1 -1
  92. package/src/components/xform/docs/2026-09 /345/212/250/346/200/201/345/255/227/346/256/265/350/247/204/345/210/231/344/270/216/346/265/201/347/250/213/346/216/247/345/210/266/346/211/247/350/241/214/351/241/272/345/272/217/350/220/275/345/234/260/346/226/271/346/241/210.md" +409 -0
  93. package/src/components/xform/docs/2026-09 /346/235/241/344/273/266/345/257/274/345/207/272/345/244/247/346/225/260/346/215/256/351/207/217/345/264/251/346/272/203/346/216/222/346/237/245.md" +389 -0
  94. package/src/components/xform/docs/2026-09 /346/265/217/350/247/210/345/231/250/345/264/251/346/272/203/346/262/273/347/220/206P0/344/273/243/347/240/201/350/257/204/345/256/241.md" +255 -0
  95. package/src/components/xform/docs/2026-09 /346/265/217/350/247/210/345/231/250/345/264/251/346/272/203/346/262/273/347/220/206P0/346/265/213/350/257/225/351/252/214/350/257/201/345/256/236/346/226/275/346/226/207/346/241/243.md" +595 -0
  96. package/src/components/xform/docs/2026-09 /347/274/226/350/276/221/350/241/250/350/241/214/345/206/205/344/277/235/345/255/230/346/240/241/351/252/214/350/214/203/345/233/264/344/270/216/345/210/227/345/277/205/345/241/253/350/247/243/346/236/220/344/277/256/345/244/215.md" +233 -0
  97. package/src/components/xform/docs/2026-09 /350/241/250/345/215/225/345/257/274/345/205/245/351/200/232/351/201/223/346/242/263/347/220/206/344/270/216/350/220/275/345/234/260/346/226/271/346/241/210.md" +745 -0
  98. package/src/components/xform/docs//346/265/217/350/247/210/345/231/250/345/264/251/346/272/203/346/262/273/347/220/206/344/270/216/344/277/256/345/244/215/350/220/275/345/234/260/346/226/271/346/241/210.md +324 -0
  99. package/src/components/xform/form-designer/designer.js +2133 -2100
  100. package/src/components/xform/form-designer/form-widget/container-widget/data-table-mixin.js +7 -0
  101. package/src/components/xform/form-designer/form-widget/container-widget/data-table-widget.vue +4 -2
  102. package/src/components/xform/form-designer/form-widget/container-widget/detail-h5-widget.vue +243 -227
  103. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-pane-widget.vue +228 -207
  104. package/src/components/xform/form-designer/form-widget/container-widget/h5-card-widget.vue +165 -136
  105. package/src/components/xform/form-designer/form-widget/dialog/formDialog.vue +30 -4
  106. package/src/components/xform/form-designer/form-widget/dialog/importDialog.vue +190 -185
  107. package/src/components/xform/form-designer/form-widget/dialog/importDialogMixin.js +2657 -1774
  108. package/src/components/xform/form-designer/form-widget/dialog/searchFormDialog.vue +27 -4
  109. package/src/components/xform/form-designer/form-widget/field-widget/a-link-widget.vue +1 -1
  110. package/src/components/xform/form-designer/form-widget/field-widget/a-text-widget.vue +1 -1
  111. package/src/components/xform/form-designer/form-widget/field-widget/area-select-widget.vue +1 -1
  112. package/src/components/xform/form-designer/form-widget/field-widget/autocomplete-widget.vue +1 -1
  113. package/src/components/xform/form-designer/form-widget/field-widget/baseAttachment-widget.vue +1 -1
  114. package/src/components/xform/form-designer/form-widget/field-widget/button-widget.vue +1 -1
  115. package/src/components/xform/form-designer/form-widget/field-widget/cascader-widget.vue +1 -1
  116. package/src/components/xform/form-designer/form-widget/field-widget/census-widget.vue +1 -1
  117. package/src/components/xform/form-designer/form-widget/field-widget/checkbox-widget.vue +1 -1
  118. package/src/components/xform/form-designer/form-widget/field-widget/color-widget.vue +1 -1
  119. package/src/components/xform/form-designer/form-widget/field-widget/copy_button-widget.vue +1 -1
  120. package/src/components/xform/form-designer/form-widget/field-widget/date-range-widget.vue +1 -1
  121. package/src/components/xform/form-designer/form-widget/field-widget/date-widget.vue +1 -1
  122. package/src/components/xform/form-designer/form-widget/field-widget/descriptions-widget.vue +1 -1
  123. package/src/components/xform/form-designer/form-widget/field-widget/divider-widget.vue +1 -1
  124. package/src/components/xform/form-designer/form-widget/field-widget/download-button-widget.vue +1 -1
  125. package/src/components/xform/form-designer/form-widget/field-widget/dropdown-item-widget.vue +1 -1
  126. package/src/components/xform/form-designer/form-widget/field-widget/dropdown-widget.vue +35 -4
  127. package/src/components/xform/form-designer/form-widget/field-widget/echart-bar-widget.vue +1 -1
  128. package/src/components/xform/form-designer/form-widget/field-widget/echart-category-widget.vue +1 -1
  129. package/src/components/xform/form-designer/form-widget/field-widget/echart-pie-widget.vue +1 -1
  130. package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +64 -10
  131. package/src/components/xform/form-designer/form-widget/field-widget/file-upload-widget.vue +1 -1
  132. package/src/components/xform/form-designer/form-widget/field-widget/form-item-wrapper.vue +14 -4
  133. package/src/components/xform/form-designer/form-widget/field-widget/html-text-widget.vue +1 -1
  134. package/src/components/xform/form-designer/form-widget/field-widget/import-button-widget.vue +19 -6
  135. package/src/components/xform/form-designer/form-widget/field-widget/import2-button-widget.vue +1 -1
  136. package/src/components/xform/form-designer/form-widget/field-widget/index.js +10 -1
  137. package/src/components/xform/form-designer/form-widget/field-widget/input-batch-widget.vue +1 -1
  138. package/src/components/xform/form-designer/form-widget/field-widget/input-widget.vue +29 -3
  139. package/src/components/xform/form-designer/form-widget/field-widget/multiSearch-widget.vue +1 -1
  140. package/src/components/xform/form-designer/form-widget/field-widget/news-list-widget.vue +1 -1
  141. package/src/components/xform/form-designer/form-widget/field-widget/number-widget.vue +1 -1
  142. package/src/components/xform/form-designer/form-widget/field-widget/oplog-widget.vue +1 -1
  143. package/src/components/xform/form-designer/form-widget/field-widget/picture-upload-widget.vue +1 -1
  144. package/src/components/xform/form-designer/form-widget/field-widget/print-button-widget.vue +1 -1
  145. package/src/components/xform/form-designer/form-widget/field-widget/print-detail-button-widget.vue +1 -1
  146. package/src/components/xform/form-designer/form-widget/field-widget/project-tag-widget.vue +1 -1
  147. package/src/components/xform/form-designer/form-widget/field-widget/radio-widget.vue +1 -1
  148. package/src/components/xform/form-designer/form-widget/field-widget/rate-widget.vue +1 -1
  149. package/src/components/xform/form-designer/form-widget/field-widget/rich-editor-widget.vue +1 -1
  150. package/src/components/xform/form-designer/form-widget/field-widget/row-col-select-widget.vue +64 -0
  151. package/src/components/xform/form-designer/form-widget/field-widget/save_submit_wf_button-widget.vue +1 -1
  152. package/src/components/xform/form-designer/form-widget/field-widget/script-input-widget.vue +1 -1
  153. package/src/components/xform/form-designer/form-widget/field-widget/search_button-widget.vue +1 -1
  154. package/src/components/xform/form-designer/form-widget/field-widget/select-export-button-widget.vue +1 -1
  155. package/src/components/xform/form-designer/form-widget/field-widget/select-export-item-button-widget.vue +6 -2
  156. package/src/components/xform/form-designer/form-widget/field-widget/select-widget.vue +1 -1
  157. package/src/components/xform/form-designer/form-widget/field-widget/singerSearch-widget.vue +1 -1
  158. package/src/components/xform/form-designer/form-widget/field-widget/singleUpload-widget.vue +145 -145
  159. package/src/components/xform/form-designer/form-widget/field-widget/slider-widget.vue +1 -1
  160. package/src/components/xform/form-designer/form-widget/field-widget/static-content-wrapper.vue +1 -1
  161. package/src/components/xform/form-designer/form-widget/field-widget/static-text-widget.vue +1 -1
  162. package/src/components/xform/form-designer/form-widget/field-widget/status-widget.vue +1 -1
  163. package/src/components/xform/form-designer/form-widget/field-widget/switch-widget.vue +1 -1
  164. package/src/components/xform/form-designer/form-widget/field-widget/table-export-button-widget.vue +3 -2
  165. package/src/components/xform/form-designer/form-widget/field-widget/tempStorage-widget.vue +1 -1
  166. package/src/components/xform/form-designer/form-widget/field-widget/text-widget.vue +1 -1
  167. package/src/components/xform/form-designer/form-widget/field-widget/textarea-widget.vue +1 -1
  168. package/src/components/xform/form-designer/form-widget/field-widget/time-range-widget.vue +1 -1
  169. package/src/components/xform/form-designer/form-widget/field-widget/time-widget.vue +1 -1
  170. package/src/components/xform/form-designer/form-widget/field-widget/title-head-widget.vue +1 -1
  171. package/src/components/xform/form-designer/form-widget/field-widget/vabSearch-widget.vue +1 -1
  172. package/src/components/xform/form-designer/form-widget/field-widget/vabUpload-widget.vue +3 -3
  173. package/src/components/xform/form-designer/form-widget/field-widget/vabUpload2-widget.vue +25 -1
  174. package/src/components/xform/form-designer/form-widget/field-widget/vue-page-widget.vue +1 -1
  175. package/src/components/xform/form-designer/indexMixin.js +27 -0
  176. package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +687 -602
  177. package/src/components/xform/form-designer/setting-panel/form-setting.vue +269 -36
  178. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/data-table-editor.vue +335 -12
  179. package/src/components/xform/form-designer/setting-panel/property-editor/container-data-table/table-column-dialog.vue +23 -7
  180. package/src/components/xform/form-designer/setting-panel/property-editor/container-detail/detail-temp-edito.vue +13 -1
  181. package/src/components/xform/form-designer/setting-panel/property-editor/container-list-h5/list-h5-editor.vue +846 -860
  182. package/src/components/xform/form-designer/setting-panel/property-editor/container-tab/tab-lazyRender-editor.vue +27 -0
  183. package/src/components/xform/form-designer/setting-panel/property-editor/event-handler/onTabChange-editor.vue +28 -0
  184. package/src/components/xform/form-designer/setting-panel/property-editor/event-handler/onTabClick-editor.vue +28 -0
  185. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import-button-editor.vue +62 -1
  186. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +142 -2
  187. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/empty-number-input.vue +51 -0
  188. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/select-export-item-button-editor.vue +27 -2
  189. package/src/components/xform/form-designer/setting-panel/property-editor/field-table-export-button/table-export-button-editor.vue +33 -3
  190. package/src/components/xform/form-designer/setting-panel/property-editor/project-tag-editor.vue +2 -4
  191. package/src/components/xform/form-designer/setting-panel/property-editor/suffixIconClickable-editor.vue +23 -0
  192. package/src/components/xform/form-designer/setting-panel/propertyRegister.js +18 -4
  193. package/src/components/xform/form-designer/toolbar-panel/index.vue +884 -874
  194. package/src/components/xform/form-designer/toolbar-panel/indexMixin.js +13 -0
  195. package/src/components/xform/form-designer/widget-panel/index.vue +11 -7
  196. package/src/components/xform/form-designer/widget-panel/indexMixin.js +15 -2
  197. package/src/components/xform/form-designer/widget-panel/widgetsConfig.js +152 -9
  198. package/src/components/xform/form-render/container-item/containerItemMixin.js +93 -8
  199. package/src/components/xform/form-render/container-item/data-table-item.vue +352 -347
  200. package/src/components/xform/form-render/container-item/data-table-mixin.js +7261 -5985
  201. package/src/components/xform/form-render/container-item/detail-h5-item.vue +48 -19
  202. package/src/components/xform/form-render/container-item/detail-item.vue +350 -446
  203. package/src/components/xform/form-render/container-item/dynamicFieldMixin.js +55 -1
  204. package/src/components/xform/form-render/container-item/list-h5-item.vue +261 -178
  205. package/src/components/xform/form-render/container-item/panel-item.vue +1 -1
  206. package/src/components/xform/form-render/container-item/tab-item.vue +177 -129
  207. package/src/components/xform/form-render/fieldControlEngine.js +218 -0
  208. package/src/components/xform/form-render/fieldControlMixin.js +536 -0
  209. package/src/components/xform/form-render/index.vue +164 -153
  210. package/src/components/xform/form-render/indexMixin.js +5443 -5311
  211. package/src/components/xform/form-render/pageDialogScope.js +54 -0
  212. package/src/components/xform/icon-picker/index.vue +1 -1
  213. package/src/components/xform/lang/en-US.js +8 -0
  214. package/src/components/xform/lang/zh-CN.js +9 -0
  215. package/src/components/xform/mixins/businessLock.js +59 -0
  216. package/src/components/xform/mixins/defaultHandle.js +713 -707
  217. package/src/components/xform/mixins/scriptHttp.js +42 -21
  218. package/src/components/xform/mixins/wfStart.js +105 -0
  219. package/src/components/xform/mixins/wfVisibility.js +33 -0
  220. package/src/components/xform/styles/census.scss +288 -0
  221. package/src/components/xform/styles/containers.scss +215 -0
  222. package/src/components/xform/styles/designer.scss +904 -0
  223. package/src/components/xform/styles/detail-temp.scss +71 -0
  224. package/src/components/xform/styles/h5-designer.scss +191 -0
  225. package/src/components/xform/styles/h5-runtime.scss +520 -0
  226. package/src/components/xform/styles/h5.scss +836 -516
  227. package/src/components/xform/styles/skins.scss +398 -0
  228. package/src/components/xform/styles/table-layout.scss +91 -0
  229. package/src/components/xform/styles/titles.scss +255 -0
  230. package/src/components/xform/utils/dynamicSchemaUtil.js +385 -361
  231. package/src/components/xform/utils/fixedQueryUtil.js +29 -4
  232. package/src/components/xform/utils/serviceNameCache.js +69 -0
  233. package/src/components/xform/utils/tableColumnHelper.js +46 -4
  234. package/src/components/xform/utils/util.js +1776 -1708
  235. package/src/core-resources/css/h5.scss +548 -0
  236. package/src/core-resources/css/iconfont.css +1447 -0
  237. package/src/core-resources/font/iconfont.ttf +0 -0
  238. package/src/core-resources/font/iconfont.woff +0 -0
  239. package/src/core-resources/font/iconfont.woff2 +0 -0
  240. package/src/core-resources/images/default-header.png +0 -0
  241. package/src/core-resources/images/ico-default_wenjian.svg +1 -0
  242. package/src/core-resources/images/ico-excel.svg +1 -0
  243. package/src/core-resources/images/ico-ftl.svg +7 -0
  244. package/src/core-resources/images/ico-html.svg +1 -0
  245. package/src/core-resources/images/ico-java.svg +1 -0
  246. package/src/core-resources/images/ico-music.svg +1 -0
  247. package/src/core-resources/images/ico-pdf.svg +1 -0
  248. package/src/core-resources/images/ico-photo.svg +1 -0
  249. package/src/core-resources/images/ico-ppt.svg +1 -0
  250. package/src/core-resources/images/ico-psd.svg +1 -0
  251. package/src/core-resources/images/ico-service.png +0 -0
  252. package/src/core-resources/images/ico-txt.svg +1 -0
  253. package/src/core-resources/images/ico-video.svg +1 -0
  254. package/src/core-resources/images/ico-vue.svg +8 -0
  255. package/src/core-resources/images/ico-wenjianjia.svg +1 -0
  256. package/src/core-resources/images/ico-wrod.svg +1 -0
  257. package/src/core-resources/images/ico-xml.svg +1 -0
  258. package/src/core-resources/images/ico-yasuobao.svg +1 -0
  259. package/src/core-resources/images/icon-error.png +0 -0
  260. package/src/core-resources/images/icon-tips.png +0 -0
  261. package/src/core-resources/images/nodata.png +0 -0
  262. package/src/core-resources/images/nodata2.png +0 -0
  263. package/src/directive/append-to-body/index.js +48 -0
  264. package/src/directive/el-dialog-center/index.js +3 -2
  265. package/src/directive/el-drag-dialog/drag.js +33 -4
  266. package/src/icons/index.js +9 -0
  267. package/src/icons/svg/404.svg +1 -0
  268. package/src/icons/svg/alert.svg +1 -0
  269. package/src/icons/svg/bug.svg +1 -0
  270. package/src/icons/svg/button.svg +1 -0
  271. package/src/icons/svg/card.svg +1 -0
  272. package/src/icons/svg/cascader-field.svg +1 -0
  273. package/src/icons/svg/census.svg +1 -0
  274. package/src/icons/svg/chart.svg +1 -0
  275. package/src/icons/svg/checkbox-field.svg +1 -0
  276. package/src/icons/svg/clipboard.svg +1 -0
  277. package/src/icons/svg/color-field.svg +1 -0
  278. package/src/icons/svg/component.svg +1 -0
  279. package/src/icons/svg/custom-component.svg +1 -0
  280. package/src/icons/svg/dashboard.svg +1 -0
  281. package/src/icons/svg/data-table.svg +1 -0
  282. package/src/icons/svg/date-field.svg +1 -0
  283. package/src/icons/svg/date-range-field.svg +1 -0
  284. package/src/icons/svg/descriptions.svg +1 -0
  285. package/src/icons/svg/divider.svg +1 -0
  286. package/src/icons/svg/document.svg +1 -0
  287. package/src/icons/svg/documentation.svg +1 -0
  288. package/src/icons/svg/drag.svg +1 -0
  289. package/src/icons/svg/echart-category.svg +1 -0
  290. package/src/icons/svg/echart-pie.svg +1 -0
  291. package/src/icons/svg/echart.svg +1 -0
  292. package/src/icons/svg/edit.svg +1 -0
  293. package/src/icons/svg/education.svg +1 -0
  294. package/src/icons/svg/email.svg +1 -0
  295. package/src/icons/svg/example.svg +1 -0
  296. package/src/icons/svg/excel.svg +1 -0
  297. package/src/icons/svg/exit-fullscreen.svg +1 -0
  298. package/src/icons/svg/eye-open.svg +1 -0
  299. package/src/icons/svg/eye.svg +1 -0
  300. package/src/icons/svg/file-upload-field.svg +1 -0
  301. package/src/icons/svg/form.svg +1 -0
  302. package/src/icons/svg/fullscreen.svg +1 -0
  303. package/src/icons/svg/github.svg +1 -0
  304. package/src/icons/svg/grid.svg +1 -0
  305. package/src/icons/svg/guide.svg +1 -0
  306. package/src/icons/svg/html-text.svg +1 -0
  307. package/src/icons/svg/ico-more.svg +1 -0
  308. package/src/icons/svg/ico-wenjianjia.svg +1 -0
  309. package/src/icons/svg/icon.svg +1 -0
  310. package/src/icons/svg/input-batch.svg +1 -0
  311. package/src/icons/svg/international.svg +1 -0
  312. package/src/icons/svg/language.svg +1 -0
  313. package/src/icons/svg/link.svg +1 -0
  314. package/src/icons/svg/list-export.svg +1 -0
  315. package/src/icons/svg/list.svg +1 -0
  316. package/src/icons/svg/lock.svg +1 -0
  317. package/src/icons/svg/message.svg +1 -0
  318. package/src/icons/svg/money.svg +1 -0
  319. package/src/icons/svg/nested.svg +1 -0
  320. package/src/icons/svg/news-list.svg +1 -0
  321. package/src/icons/svg/node-tree.svg +1 -0
  322. package/src/icons/svg/number-field.svg +1 -0
  323. package/src/icons/svg/password.svg +1 -0
  324. package/src/icons/svg/pdf.svg +1 -0
  325. package/src/icons/svg/people.svg +1 -0
  326. package/src/icons/svg/peoples.svg +1 -0
  327. package/src/icons/svg/picture-upload-field.svg +1 -0
  328. package/src/icons/svg/qq.svg +1 -0
  329. package/src/icons/svg/query.svg +1 -0
  330. package/src/icons/svg/radio-field.svg +1 -0
  331. package/src/icons/svg/rate-field.svg +1 -0
  332. package/src/icons/svg/redo.svg +1 -0
  333. package/src/icons/svg/rich-editor-field.svg +1 -0
  334. package/src/icons/svg/search.svg +1 -0
  335. package/src/icons/svg/searchbox.svg +1 -0
  336. package/src/icons/svg/section.svg +1 -0
  337. package/src/icons/svg/select-field.svg +1 -0
  338. package/src/icons/svg/shopping.svg +1 -0
  339. package/src/icons/svg/size.svg +1 -0
  340. package/src/icons/svg/skill.svg +1 -0
  341. package/src/icons/svg/slider-field.svg +1 -0
  342. package/src/icons/svg/slot-component.svg +1 -0
  343. package/src/icons/svg/slot-field.svg +1 -0
  344. package/src/icons/svg/star.svg +1 -0
  345. package/src/icons/svg/static-text.svg +1 -0
  346. package/src/icons/svg/status.svg +1 -0
  347. package/src/icons/svg/sub-form.svg +1 -0
  348. package/src/icons/svg/switch-field.svg +1 -0
  349. package/src/icons/svg/tab.svg +1 -0
  350. package/src/icons/svg/table.svg +1 -0
  351. package/src/icons/svg/text-field.svg +1 -0
  352. package/src/icons/svg/text.svg +1 -0
  353. package/src/icons/svg/textarea-field.svg +1 -0
  354. package/src/icons/svg/theme.svg +1 -0
  355. package/src/icons/svg/time-field.svg +1 -0
  356. package/src/icons/svg/time-range-field.svg +1 -0
  357. package/src/icons/svg/tips-text.svg +1 -0
  358. package/src/icons/svg/title-head.svg +1 -0
  359. package/src/icons/svg/tree-pane.svg +1 -0
  360. package/src/icons/svg/tree-table.svg +1 -0
  361. package/src/icons/svg/tree.svg +1 -0
  362. package/src/icons/svg/undo.svg +1 -0
  363. package/src/icons/svg/uploadbox.svg +1 -0
  364. package/src/icons/svg/user.svg +1 -0
  365. package/src/icons/svg/vf-box.svg +1 -0
  366. package/src/icons/svg/vf-dialog.svg +1 -0
  367. package/src/icons/svg/vf-drawer.svg +1 -0
  368. package/src/icons/svg/vue-sfc.svg +1 -0
  369. package/src/icons/svg/wechat.svg +1 -0
  370. package/src/icons/svg/zip.svg +1 -0
  371. package/src/index.js +2 -510
  372. package/src/index.next.js +5 -0
  373. package/src/index.sync.js +5 -0
  374. package/src/layout/components/Sidebar/default.vue +1656 -1655
  375. package/src/layout/components/TagsView/index.vue +330 -323
  376. package/src/layout/components/TagsView/style.scss +92 -0
  377. package/src/layout/components/watermark/index.vue +1 -1
  378. package/src/layout/defaultLayout.vue +2 -2
  379. package/src/router/index.js +43 -48
  380. package/src/router/modules/customer.js +12 -0
  381. package/src/store/modules/settings.js +1 -1
  382. package/src/store/modules/tagsView.js +241 -217
  383. package/src/store/modules/user.js +16 -12
  384. package/src/styles/btn.scss +315 -0
  385. package/src/styles/dialog.scss +1710 -0
  386. package/src/styles/element-ui.scss +1076 -0
  387. package/src/styles/element-variables.scss +31 -0
  388. package/src/styles/global.scss +115 -0
  389. package/src/styles/index.scss +245 -0
  390. package/src/styles/layout-skins.scss +840 -0
  391. package/src/styles/legacy-base.scss +19 -0
  392. package/src/styles/menu-icons.scss +75 -0
  393. package/src/styles/mixin.scss +80 -0
  394. package/src/styles/nprogress.scss +14 -0
  395. package/src/styles/page-shell.scss +723 -0
  396. package/src/styles/sidebar.scss +296 -0
  397. package/src/styles/split-handle.scss +52 -0
  398. package/src/styles/theme-variables.scss +7 -0
  399. package/src/styles/transition.scss +48 -0
  400. package/src/styles/utilities.scss +253 -0
  401. package/src/styles/variables.scss +72 -0
  402. package/src/utils/baseDictsCache.js +197 -0
  403. package/src/utils/chunkLoadError.js +24 -0
  404. package/src/utils/featureResources.js +57 -0
  405. package/src/utils/importLimit.js +72 -0
  406. package/src/utils/pdfUtil.js +6 -1
  407. package/src/utils/request.js +149 -9
  408. package/src/utils/resolveViewComponent.js +45 -90
  409. package/src/utils/runtimeRecovery.js +105 -0
  410. package/src/utils/swiperLoader.js +20 -0
  411. package/src/utils/vab.js +1334 -1283
  412. package/src/utils/xlsxLoader.js +29 -0
  413. package/src/views/bd/setting/formVersion/compareContMixin.scss +1 -1
  414. package/src/views/bd/setting/form_template/edit.vue +378 -356
  415. package/src/views/bd/setting/form_template/formDesignerDialog.vue +6 -0
  416. package/src/views/bd/setting/form_template/formTemplateType.js +43 -0
  417. package/src/views/bd/setting/form_template/list.vue +304 -303
  418. package/src/views/bd/setting/form_template/mixins/edit.js +344 -280
  419. package/src/views/bd/setting/form_template/mixins/list.js +749 -721
  420. package/src/views/bd/setting/form_template/mixins/list2.js +412 -411
  421. package/src/views/bd/setting/form_template/mixins/wf_list.js +431 -430
  422. package/src/views/mobile/user/area/dialog.vue +1 -1
  423. package/src/views/mobile/user/user/dialog.vue +1 -1
  424. package/src/views/user/bill_setting/mixins/wf.js +8 -0
  425. package/src/views/user/bill_setting/render.vue +1 -1
  426. package/src/views/user/commMenu/index.vue +3 -1
  427. package/src/views/user/commMenu/style.scss +123 -0
  428. package/src/views/user/common_attribute/edit.vue +2 -0
  429. package/src/views/user/common_attribute/itemEdit.vue +2 -0
  430. package/src/views/user/file_view_ins/list.vue +970 -970
  431. package/src/views/user/form/form_template/list.vue +527 -506
  432. package/src/views/user/form/vform/designer.vue +823 -821
  433. package/src/views/user/form/view/list.vue +24 -1
  434. package/src/views/user/home/default.vue +1124 -1117
  435. package/src/views/user/home/default2.vue +12 -8
  436. package/src/views/user/home/index.vue +102 -102
  437. package/src/views/user/home/wjl/content.vue +1581 -1569
  438. package/src/views/user/intf_permission/edit.vue +230 -0
  439. package/src/views/user/intf_permission/list.vue +196 -0
  440. package/src/views/user/menuFallback/index.vue +23 -0
  441. package/src/views/user/notify_message/dialog.vue +139 -139
  442. package/src/views/user/outLink/form_view.vue +202 -202
  443. package/src/views/user/outLink/index.vue +110 -110
  444. package/src/views/user/role/edit.vue +4 -0
  445. package/src/views/user/role/role-box.scss +83 -0
  446. package/src/views/user/role/voc_edit.vue +4 -0
  447. package/src/views/user/user/list.vue +28 -6
  448. package/src/views/user/wf/iframe/index.vue +51 -51
  449. package/src/views/user/wf/iframe/index2.vue +64 -64
  450. package/src/views/user/wf/wf_diy_attribute/edit.vue +1 -1
  451. package/src/views/user/wf/wf_manage/list2.vue +871 -871
  452. package/src/views/user/wf/wf_manage/wfContentDialog.vue +177 -126
  453. package/src/views/user/wf/wf_obj_config/activiti_wf.vue +134 -133
  454. package/src/views/user/wf/wf_obj_config/importItemDialog.vue +1 -1
  455. package/src/views/user/wf/wf_obj_config/list.vue +747 -746
  456. package/src/views/user/wf/wf_obj_config/list_form.vue +374 -373
  457. package/templates/child-app/.env +3 -0
  458. package/templates/child-app/README.md +49 -0
  459. package/templates/child-app/app.config.js +6 -0
  460. package/templates/child-app/babel.config.js +1 -0
  461. package/templates/child-app/core-resources.config.js +15 -0
  462. package/templates/child-app/gitignore +7 -0
  463. package/templates/child-app/package.json +34 -0
  464. package/templates/child-app/public/index.html +12 -0
  465. package/templates/child-app/src/assets/401_images/401.gif +0 -0
  466. package/templates/child-app/src/assets/404_images/404.png +0 -0
  467. package/templates/child-app/src/assets/404_images/404_cloud.png +0 -0
  468. package/templates/child-app/src/assets/logo.png +0 -0
  469. package/templates/child-app/src/corejsConfig.js +2 -0
  470. package/templates/child-app/src/icons/index.js +2 -0
  471. package/templates/child-app/src/icons/svg/child-demo.svg +1 -0
  472. package/templates/child-app/src/layout/index.vue +4 -0
  473. package/templates/child-app/src/main.js +5 -0
  474. package/templates/child-app/src/prefixConfig.js +13 -0
  475. package/templates/child-app/src/resources/css/login.scss +29 -0
  476. package/templates/child-app/src/resources/images/bg-login5.jpg +0 -0
  477. package/templates/child-app/src/resources/images/home-img.png +0 -0
  478. package/templates/child-app/src/router/modules/customer.js +3 -0
  479. package/templates/child-app/src/settings.js +25 -0
  480. package/templates/child-app/src/styles/app.scss +2 -0
  481. package/templates/child-app/src/views/demo/detail.vue +19 -0
  482. package/templates/child-app/src/views/demo/list.vue +38 -0
  483. package/templates/child-app/src/views/user/login/index.vue +18 -0
  484. package/templates/child-app/vue.config.js +107 -0
  485. package/src/components/xform/form-render/container-item/dynamicFieldEngine.js +0 -285
  486. package/src/components/xform/form-render/formDynamicFieldMixin.js +0 -131
  487. package/src/views/demo/bizTab/bill/billConfig.js +0 -41
  488. package/src/views/demo/bizTab/bill/detail.vue +0 -436
  489. package/src/views/demo/bizTab/bill/list.vue +0 -288
  490. package/src/views/demo/bizTab/bill/productDialog.vue +0 -176
  491. package/src/views/demo/bizTab/simple/billApi.js +0 -123
  492. package/src/views/demo/bizTab/simple/detail.vue +0 -407
  493. package/src/views/demo/bizTab/simple/list.vue +0 -217
  494. package/src/views/demo/bizTab/standalone/index.vue +0 -121
  495. package/src/views/demo/bizTab/wf/billConfig.js +0 -44
  496. package/src/views/demo/bizTab/wf/detail.vue +0 -661
  497. package/src/views/demo/bizTab/wf/list.vue +0 -242
  498. package/src/views/user/outLink/cc_form_view.vue +0 -188
  499. /package/src/{resources → core-resources}/js/base/common.js +0 -0
@@ -0,0 +1,595 @@
1
+ # 浏览器崩溃治理 P0 测试验证实施文档
2
+
3
+ ## 1. 文档信息
4
+
5
+ - 编制日期:2026-09-20
6
+ - 测试仓库:`D:\develop\code\company\2024\dev\sf-cloud-web-com-dev@publish_dev`
7
+ - 对照方案:`src/components/xform/docs/浏览器崩溃治理与修复落地方案.md`
8
+ - 代码评审:`src/components/xform/docs/2026-09 浏览器崩溃治理P0代码评审.md`
9
+ - 验证范围:数据表格查询治理、行级运行时释放、自动保存 worker、Blob URL 释放
10
+ - 不在本轮范围:KeepAlive 上限、dirty 页面保护、outLink LRU、数据量硬上限、正式仓同步
11
+ - 当前构建基线:生产构建 Hash `593070bfea61c357`
12
+
13
+ ## 2. 验证目标
14
+
15
+ 本轮验证必须回答以下问题:
16
+
17
+ 1. 连续查询、空结果和乱序响应不会让旧数据覆盖新数据,也不会持续保留旧行 schema/ref。
18
+ 2. 粘贴、失焦和 change 自动保存始终串行,同一行连续修改能够合并并补存最新版本。
19
+ 3. 删行或销毁表格时,等待中的自动保存会失效,正在执行的自动保存会被取消且不再回写。
20
+ 4. 上传预览、附件预览、下载、打印和导入结果产生的 Blob URL 能在对应生命周期结束后释放。
21
+ 5. 两小时综合操作后,JS heap、DOM、事件监听和 Blob 数量不存在持续单调增长趋势。
22
+
23
+ ## 3. 环境与数据准备
24
+
25
+ ### 3.1 浏览器与工具
26
+
27
+ - Chrome 当前生产环境同版本,另准备一个最新稳定版用于交叉验证。
28
+ - DevTools:Performance Monitor、Memory、Network。
29
+ - Chrome 任务管理器:观察标签页总内存。
30
+ - 测试环境后端应允许配置接口延迟,建议准备 `0 ms`、`2 s`、`8 s` 三档。
31
+
32
+ ### 3.2 测试页面
33
+
34
+ 至少准备以下表单:
35
+
36
+ | 编号 | 页面 | 必要配置 |
37
+ | --- | --- | --- |
38
+ | T1 | 普通分页表格 | 200 行/页、包含文本和选项列 |
39
+ | T2 | 编辑表格 | 开启 blur/change 自动保存 |
40
+ | T3 | 可粘贴编辑表格 | 开启 paste 自动保存和自动补行 |
41
+ | T4 | 树形编辑表格 | 至少三级节点,支持展开、增删和单行保存 |
42
+ | T5 | 上传与附件表单 | 普通上传、OBS、VabUpload2、图片附件预览 |
43
+ | T6 | 导入/下载/打印页面 | 可生成导入结果、文件下载和打印预览 |
44
+
45
+ ### 3.3 数据与网络条件
46
+
47
+ - 普通列表数据不少于 3 页,每页 200 行。
48
+ - 准备一个必定返回空结果的查询条件。
49
+ - 准备两个结果明显不同的条件 A/B,便于识别乱序覆盖。
50
+ - 准备 1 MB、10 MB 图片各一张,以及普通文档、Excel 文件。
51
+ - 测试自动保存时,在 Network 面板保留请求记录并显示时间线。
52
+
53
+ ### 3.4 浏览器测试前的具体操作
54
+
55
+ #### 3.4.1 打开并固定 DevTools
56
+
57
+ 1. 使用 Chrome 打开测试环境并进入待测表单页面。
58
+ 2. 按 `F12`,或在页面空白处右键选择“检查”。
59
+ 3. 将 DevTools 停靠到右侧,避免遮挡表格按钮。
60
+ 4. 打开 **Network** 面板,勾选 **Preserve log**(保留日志)和 **Disable cache**(停用缓存)。
61
+ 5. 打开 **Console** 面板,点击左上角清空按钮,确保后续异常来自本次操作。
62
+ 6. 打开 DevTools 右上角 `⋮` → **More tools** → **Performance monitor**,勾选:
63
+ - JS heap size
64
+ - DOM Nodes
65
+ - JS event listeners
66
+ - Documents
67
+ 7. 测试期间不要关闭 DevTools;关闭 DevTools 后 Disable cache 会失效。
68
+
69
+ #### 3.4.2 获取当前数据表格的 Vue 实例
70
+
71
+ 优先使用 Vue Devtools:
72
+
73
+ 1. 打开 DevTools 的 **Vue** 面板。
74
+ 2. 在组件树中选择当前表单内的数据表格组件。
75
+ 3. 切回 Console,输入 `$vm0`。若输出对象包含 `fieldSchemaMap`、`rowIdData`,说明选对组件。
76
+ 4. 输入以下命令固定该实例:
77
+
78
+ ```js
79
+ window.__tableVm = $vm0
80
+ ```
81
+
82
+ 未安装 Vue Devtools 时:
83
+
84
+ 1. 打开 **Elements** 面板。
85
+ 2. 点击左上角箭头图标,回到页面点击表格中的任意单元格。
86
+ 3. 切回 Console,复制执行:
87
+
88
+ ```js
89
+ window.__tableVm = (() => {
90
+ let vm = $0 && $0.__vue__
91
+ while (vm && !("fieldSchemaMap" in vm && "rowIdData" in vm)) {
92
+ vm = vm.$parent
93
+ }
94
+ return vm
95
+ })()
96
+ ```
97
+
98
+ 4. 执行以下命令确认。返回 `true` 才继续测试:
99
+
100
+ ```js
101
+ !!window.__tableVm
102
+ ```
103
+
104
+ 如果返回 `false`,重新在 Elements 中选择更靠近表格主体的 DOM 节点后再次执行。页面刷新或重新进入表单后,需要重新获取实例。
105
+
106
+ #### 3.4.3 一键检查表格运行时状态
107
+
108
+ 在 Console 中复制执行以下代码。执行一次后,后续输入 `checkTableRuntime()` 即可检查:
109
+
110
+ ```js
111
+ window.checkTableRuntime = function () {
112
+ const vm = window.__tableVm
113
+ if (!vm) throw new Error("请先按 3.4.2 获取 __tableVm")
114
+
115
+ const rows = vm.formModel?.[vm.fieldKeyName] || []
116
+ const validKeys = new Set(rows.map(row => row?._X_ROW_KEY).filter(Boolean))
117
+ const schemaKeys = Object.keys(vm.fieldSchemaMap || {})
118
+ const staleSchemas = schemaKeys.filter(key => !validKeys.has(key))
119
+ const staleRefs = Object.entries(vm.refList || {})
120
+ .filter(([, ref]) => {
121
+ const rowKey = ref?.tableParam?.row?._X_ROW_KEY
122
+ return rowKey && !validKeys.has(rowKey)
123
+ })
124
+ .map(([key]) => key)
125
+
126
+ const result = {
127
+ rows: rows.length,
128
+ rowIds: (vm.rowIdData || []).length,
129
+ schemas: schemaKeys.length,
130
+ staleSchemas,
131
+ refs: Object.keys(vm.refList || {}).length,
132
+ staleRefs,
133
+ autoSavePendingRows: Object.keys(vm.editAutoSavePendingRows || {}).length,
134
+ autoSaveOrder: [...(vm.editAutoSaveOrder || [])],
135
+ autoSaveWorkerRunning: !!vm.editAutoSaveWorkerRunning,
136
+ autoSaveActiveRowKey: vm.editAutoSaveActiveRowKey || null,
137
+ tableDestroyed: !!vm.tableDestroyed,
138
+ }
139
+ console.table(result)
140
+ return result
141
+ }
142
+ ```
143
+
144
+ 说明:
145
+
146
+ - `rows`:当前表单模型中的有效行数。
147
+ - `rowIds`:组件维护的有效行键数,正常情况下应与 rows 相等。
148
+ - `schemas`:已经创建的行级 schema 数量;虚拟滚动/懒建模式下允许小于 rows。
149
+ - `staleSchemas`:已不属于当前数据的 schema,必须为空数组。
150
+ - `staleRefs`:已不属于当前数据的组件引用,组件更新完成后必须为空数组。
151
+ - `autoSavePendingRows`:等待或正在处理的自动保存行数。
152
+ - `autoSaveOrder`:尚未轮到执行的行键顺序。
153
+
154
+ #### 3.4.4 查看请求是否并发、取消或乱序
155
+
156
+ 1. 打开 **Network**,点击过滤器中的 **Fetch/XHR**。
157
+ 2. 在 Filter 输入保存或查询接口关键字;不知道关键字时先操作一次,再从新增请求中确认 URL。
158
+ 3. 右键表头,勾选 **Start Time**、**Duration**、**Waterfall**。
159
+ 4. 查询取消成功时,请求的 Status 通常显示 `(canceled)`,Waterfall 会提前结束。
160
+ 5. 自动保存串行成功时,多条保存请求的 Waterfall 不应横向重叠:后一条必须在前一条结束后才开始。
161
+ 6. 右键请求选择 **Save all as HAR with content**,保存为测试证据。
162
+
163
+ #### 3.4.5 使用 DevTools 模拟慢请求
164
+
165
+ 仅用于没有后端延迟开关时:
166
+
167
+ 1. 在 Network 面板找到 **No throttling** 下拉框。
168
+ 2. 点击下拉框 → **Add...**,新建配置:
169
+ - 名称:`P0 Slow 8s`
170
+ - Download:`50 kbit/s`
171
+ - Upload:`50 kbit/s`
172
+ - Latency:`8000 ms`
173
+ 3. 发起需要变慢的第一个请求后,立即切回 **No throttling**,再发起第二个请求。
174
+ 4. 注意:该方式会影响页面的所有网络请求。用例结束后必须恢复 **No throttling**。
175
+
176
+ 后端延迟开关比浏览器限速更准确;如果二者都可用,优先使用后端延迟。
177
+
178
+ ## 4. 自动化验证
179
+
180
+ ### 4.1 相关测试范围
181
+
182
+ ```text
183
+ tests/unit/components/xform/dataTableClipboard.spec.js
184
+ tests/unit/components/xform/fieldBlurAutoSave.spec.js
185
+ tests/unit/components/xform/saveReconcile.spec.js
186
+ tests/unit/components/xform/exportQuerySideEffects.spec.js
187
+ ```
188
+
189
+ 重点断言:
190
+
191
+ - 粘贴和失焦更新同一等待项,最大并发保存数为 1。
192
+ - 同一行保存期间继续修改会再次保存最新版本。
193
+ - 删除活动行会取消请求,并从等待顺序中移除。
194
+ - CancelToken 同时传递给保存写入和保存后回查。
195
+ - 查询延迟副作用受查询代次限制。
196
+
197
+ ### 4.2 标准执行命令
198
+
199
+ 仓库测试依赖修正后使用:
200
+
201
+ ```bash
202
+ npx jest --clearCache
203
+ npx vue-cli-service test:unit tests/unit/components/xform/dataTableClipboard.spec.js tests/unit/components/xform/fieldBlurAutoSave.spec.js tests/unit/components/xform/saveReconcile.spec.js tests/unit/components/xform/exportQuerySideEffects.spec.js --runInBand
204
+ ```
205
+
206
+ 当前工作副本的 `jest.config.js` 仍引用未安装的 `vue-jest`,实际安装的是 `@vue/vue2-jest`。在正式 CI 前应统一配置;本轮已通过运行时覆盖转换器和 `jsdom` 完成验证,结果为:
207
+
208
+ ```text
209
+ Test Suites: 4 passed, 4 total
210
+ Tests: 30 passed, 30 total
211
+ Snapshots: 0 total
212
+ ```
213
+
214
+ ### 4.3 构建验证
215
+
216
+ ```bash
217
+ npx vue-cli-service build
218
+ ```
219
+
220
+ 通过标准:
221
+
222
+ - 退出码为 0。
223
+ - 输出 `DONE Build complete`。
224
+ - 不出现由本次修改引入的解析、依赖或打包错误。
225
+ - 现有样式导出、CSS 顺序和包体积警告单独登记,不作为本轮 P0 阻断项。
226
+
227
+ ## 5. 数据表格专项验证
228
+
229
+ ### 5.1 连续查询
230
+
231
+ 浏览器操作步骤:
232
+
233
+ 1. 打开 T1 页面,按 3.4.2 获取 `__tableVm`。
234
+ 2. 在 Console 执行 `checkTableRuntime()`,截图保存第一次结果。
235
+ 3. 切到 Network → Fetch/XHR,点击清空按钮。
236
+ 4. 回到页面,在查询区填写一个能返回约 200 行的条件。
237
+ 5. 连续快速点击页面“查询”按钮 10 次,点击间隔约 100–300 ms,不等待前一次结束。
238
+ 6. 切回 Network,确认前 9 个请求多数显示 `(canceled)`,最后一个请求正常完成。
239
+ 7. 确认表格 loading 消失,页面数据属于最后一次点击使用的条件。
240
+ 8. 在 Console 执行 `checkTableRuntime()`,确认 `staleSchemas`、`staleRefs` 都为 `[]`。
241
+ 9. 重复第 4–8 步 10 轮,共计 100 次查询;每轮保存一次 Console 截图。
242
+ 10. 最后一轮结束后等待 10 秒,在 Performance monitor 记录 JS heap、DOM Nodes、Event Listeners。
243
+
244
+ 若要避免人工点击次数不准,可在 Console 使用下面的点击脚本。先在 Elements 中选中页面的“查询”按钮,再执行:
245
+
246
+ ```js
247
+ const queryButton = $0
248
+ let clickCount = 0
249
+ const clickTimer = setInterval(() => {
250
+ queryButton.click()
251
+ clickCount += 1
252
+ if (clickCount >= 10) clearInterval(clickTimer)
253
+ }, 200)
254
+ ```
255
+
256
+ 执行前必须确认 `$0` 就是查询按钮,避免误点删除、提交等其他按钮。
257
+
258
+ 通过标准:
259
+
260
+ - 页面始终显示最后一次查询结果。
261
+ - 被取消请求不弹错误框。
262
+ - loading 最终关闭,不存在永久遮罩。
263
+ - `rowIdData` 与当前有效行一一对应。
264
+ - `fieldSchemaMap` 不包含已被查询替换的行键。
265
+ - `refList` 不包含已卸载行的字段组件引用。
266
+
267
+ ### 5.2 有数据与空结果交替
268
+
269
+ 浏览器操作步骤:
270
+
271
+ 1. 在 T1 查询区输入“有数据条件”,点击“查询”,等待表格 loading 完全消失。
272
+ 2. 如果是树表,展开至少 3 个节点;如果是普通表,双击或点击至少 5 个可编辑单元格,使行组件实际挂载。
273
+ 3. 在 Console 执行并记录:
274
+
275
+ ```js
276
+ checkTableRuntime()
277
+ ```
278
+
279
+ 4. 回到查询区,将条件改成预先准备的“空结果条件”,点击“查询”。
280
+ 5. 等待表格显示“暂无数据”且 loading 消失。
281
+ 6. 为覆盖 VXE 旧行卸载和下一宏任务清理窗口,在 Console 执行:
282
+
283
+ ```js
284
+ setTimeout(() => {
285
+ const result = checkTableRuntime()
286
+ console.assert(result.rows === 0, "rows 未清空", result)
287
+ console.assert(result.rowIds === 0, "rowIdData 未清空", result)
288
+ console.assert(result.schemas === 0, "fieldSchemaMap 未清空", result)
289
+ console.assert(result.staleRefs.length === 0, "仍有旧行 ref", result)
290
+ }, 1000)
291
+ ```
292
+
293
+ 7. Console 没有出现红色 Assertion failed 才算本轮通过。
294
+ 8. 再输入“有数据条件”查询,确认数据可重新正常渲染和编辑。
295
+ 9. 重复第 2–8 步 20 轮。
296
+ 10. 第 1、10、20 轮分别保存 Console 截图和 Network HAR。
297
+
298
+ 通过标准:
299
+
300
+ - 空结果时 `rowIdData.length === 0`。
301
+ - 空结果时 `Object.keys(fieldSchemaMap).length === 0`。
302
+ - 旧行 ref 在组件更新后被清除。
303
+ - 页面无卡顿、递归重建或控制台异常。
304
+
305
+ ### 5.3 乱序响应
306
+
307
+ 浏览器操作步骤:
308
+
309
+ 1. 为条件 A 选择一个容易识别的结果,例如状态“草稿”;条件 B 选择明显不同的结果,例如状态“已完成”。
310
+ 2. 在 Network 选择 `P0 Slow 8s`,输入条件 A 并点击“查询”。
311
+ 3. 请求出现在 Network 后,立即切换为 **No throttling**。
312
+ 4. 在 1 秒内输入条件 B 并点击“查询”。
313
+ 5. 等待所有请求结束,确认页面只显示条件 B 的结果。
314
+ 6. 在 Network 检查 A 请求为 canceled;若服务端已经返回,也必须确认其完成后页面没有切回 A。
315
+ 7. 在 Console 执行 `checkTableRuntime()`,确认没有 A 对应的旧 schema/ref。
316
+ 8. 交换 A/B 和限速顺序再执行,共完成 20 轮。
317
+
318
+ 通过标准:
319
+
320
+ - 最终数据始终属于最后发起的查询。
321
+ - 旧响应不触发 `tableOption.callback` 或 `formScriptCallback`。
322
+ - 树表旧响应不再展开旧行对象。
323
+ - 导出请求不被普通查询取消,普通查询也不等待导出结束。
324
+
325
+ ### 5.4 增删行与树表
326
+
327
+ 步骤:
328
+
329
+ 1. 普通表新增、删除各 50 次。
330
+ 2. 编辑表新增临时行、删除临时行各 30 次。
331
+ 3. 树表分别删除叶子节点、父节点及整棵子树。
332
+ 4. 查询刷新后重复上述操作。
333
+
334
+ 通过标准:
335
+
336
+ - 删除后 `rowIdData` 不再包含对应 `_X_ROW_KEY`。
337
+ - 对应 `fieldSchemaMap[rowKey]`、自动保存定时器和等待项被释放。
338
+ - 删除子树时所有后代运行时状态一并释放。
339
+ - 不出现幽灵行 schema、错误展开或已删除行重新出现。
340
+
341
+ ## 6. 自动保存专项验证
342
+
343
+ ### 6.1 同行连续修改
344
+
345
+ 浏览器操作步骤:
346
+
347
+ 1. 打开 T2,在 Network 过滤出单行保存接口并清空已有记录。
348
+ 2. 将保存接口延迟设为 2 秒。
349
+ 3. 在同一行同一文本字段中连续输入 10 个字符,每次间隔小于 `autoSaveDelay`,最后点击表格其他单元格触发失焦。
350
+ 4. 第一条保存请求出现在 Network 后,立即回到同一行继续输入 5 个字符并再次失焦。
351
+ 5. 在保存期间多次执行 `checkTableRuntime()`,记录 `autoSavePendingRows`、`autoSaveWorkerRunning` 和 `autoSaveActiveRowKey`。
352
+ 6. 等待请求全部结束,刷新页面或重新查询该行,核对后端保存值。
353
+
354
+ 通过标准:
355
+
356
+ - debounce 阶段合并为一个等待项。
357
+ - 同一时间最多存在一个保存请求。
358
+ - 首次保存完成后,如版本发生变化,会补存一次最新版本。
359
+ - 最终后端值与页面最后一次修改一致。
360
+
361
+ ### 6.2 粘贴与失焦竞争
362
+
363
+ 浏览器操作步骤:
364
+
365
+ 1. 在 Excel 或文本编辑器准备一行多列数据,复制到剪贴板。
366
+ 2. 打开 T3,点击目标起始单元格,按 `Ctrl+V` 粘贴。
367
+ 3. 粘贴内容出现后,不等待保存完成,立即点击该行文本字段,追加文字并点击表格外区域触发失焦。
368
+ 4. 打开 Network 查看保存请求 Waterfall;两条请求不得横向重叠。
369
+ 5. 在 Console 执行 `checkTableRuntime()`,同一时刻应只有一个 `autoSaveActiveRowKey`。
370
+ 6. 请求完成后刷新页面,确认最后追加的文字仍然存在。
371
+ 7. 保存接口使用 2 秒延迟执行 20 轮,再使用 8 秒延迟执行 20 轮。
372
+
373
+ 通过标准:
374
+
375
+ - paste、blur、change 均进入同一个 worker。
376
+ - Network 时间线上保存请求不重叠。
377
+ - 同一 `_X_ROW_KEY` 只保留一个等待项,通过 `version` 补存最新数据。
378
+ - 不出现“正在保存”后任务被当成成功丢弃的情况。
379
+
380
+ ### 6.3 多行队列上限
381
+
382
+ 浏览器操作步骤:
383
+
384
+ 1. 保存接口延迟设为 8 秒。
385
+ 2. 从第 1 行开始,逐行修改一个字段并按 `Tab` 进入下一行,连续操作 25 行。
386
+ 3. 操作过程中在 Console 反复执行 `checkTableRuntime()`。
387
+ 4. 记录 `autoSavePendingRows` 的最大值、页面警告提示和 Network 实际请求数。
388
+
389
+ 通过标准:
390
+
391
+ - 同时保留的等待行不超过 20。
392
+ - 超出时出现“自动保存任务较多,请稍后再编辑”提示。
393
+ - 不产生超过限制的并发请求。
394
+ - 已进入队列的 20 行按顺序处理。
395
+
396
+ ### 6.4 保存中删除行
397
+
398
+ 浏览器操作步骤:
399
+
400
+ 1. 将保存接口延迟设为 8 秒,修改一行并失焦。
401
+ 2. 等 Network 中出现保存请求后,记下 Console 中的 `autoSaveActiveRowKey`。
402
+ 3. 在请求返回前点击该行“删除”,按页面提示确认。
403
+ 4. 回到 Network,确认保存或保存后回查请求变为 `(canceled)`。
404
+ 5. 在 Console 执行 `checkTableRuntime()`,确认活动行键、等待数组、schema 中均不存在被删行。
405
+ 6. 等待超过 8 秒,确认行没有重新出现,也没有保存失败弹窗。
406
+ 7. 普通编辑表和树形编辑表各执行 10 次。
407
+
408
+ 通过标准:
409
+
410
+ - 当前请求显示为 canceled,或被客户端 CancelToken 中止。
411
+ - 等待 map、顺序队列和活动行键不再包含该行。
412
+ - 响应到达后不重新插入、不回写、不触发保存成功后的业务脚本。
413
+ - 不弹“保存失败”错误。
414
+
415
+ ### 6.5 保存中关闭页签
416
+
417
+ 浏览器操作步骤:
418
+
419
+ 1. 将保存接口延迟设为 8 秒,连续修改至少 5 行并逐行失焦。
420
+ 2. 执行 `checkTableRuntime()`,确认一行正在保存且存在等待行。
421
+ 3. 在 Network 观察到活动保存请求后,点击系统页签上的关闭按钮;不要只切换到其他页签,因为 KeepAlive 切换只会触发 `deactivated`。
422
+ 4. Network 中确认活动自动保存被取消。
423
+ 5. 等待超过 8 秒,观察页面右上角或消息区域,确认没有来自已关闭页面的错误提示。
424
+ 6. 从菜单重新打开该页面,重新按 3.4.2 获取新实例,确认页面可以正常查询和编辑。
425
+
426
+ 通过标准:
427
+
428
+ - 当前自动保存被取消。
429
+ - 定时器、等待 map、顺序队列被清空。
430
+ - 销毁页面不再弹消息或执行表格回写。
431
+ - Heap Snapshot 中旧表格实例可在强制 GC 后回收。
432
+
433
+ ## 7. Blob URL 专项验证
434
+
435
+ ### 7.1 验证矩阵
436
+
437
+ | 场景 | 循环次数 | 释放时机 |
438
+ | --- | ---: | --- |
439
+ | 普通上传预览、删除 | 50 | 单文件删除 |
440
+ | 普通上传粘贴、取消 | 50 | 粘贴项删除或弹窗关闭 |
441
+ | OBS 上传预览 | 50 | 删除或弹窗关闭 |
442
+ | VabUpload2 上传预览 | 50 | 删除或弹窗关闭 |
443
+ | 表单附件预览 | 50 | 值替换、附件删除、组件销毁 |
444
+ | 二维码文件解析 | 50 | 文件替换、清空、组件销毁 |
445
+ | 聊天附件 | 50 | 附件删除、组件销毁 |
446
+ | 文件下载/导入结果 | 50 | 点击下载后的下一宏任务 |
447
+ | 打印预览 | 20 | 创建 60 秒后 |
448
+
449
+ ### 7.2 检查方法
450
+
451
+ 浏览器操作步骤:
452
+
453
+ 1. 按 `F12` 打开 DevTools → **Memory**。
454
+ 2. 选择 **Heap snapshot**,点击 **Take snapshot**,命名或记录为 A(操作前)。
455
+ 3. Snapshot A 完成后,点击 DevTools 顶部垃圾桶图标 **Collect garbage**。
456
+ 4. 回到页面执行表格 7.1 中对应操作。例如普通上传:
457
+ 1. 点击“上传附件”。
458
+ 2. 选择测试图片并等待预览出现。
459
+ 3. 点击文件右侧删除按钮。
460
+ 4. 关闭上传弹窗。
461
+ 5. 重复 50 次。
462
+ 5. 操作完成但尚未等待释放时,回到 Memory 再拍 Snapshot B。
463
+ 6. 按场景完成释放动作:删除文件、替换值、关闭弹窗或关闭页面;打印预览需额外等待 60 秒。
464
+ 7. 点击 **Collect garbage**,连续点击两次,每次间隔约 2 秒。
465
+ 8. 再拍 Snapshot C(释放后)。
466
+ 9. 选择 Snapshot C 顶部视图下拉框中的 **Comparison**,基准选择 Snapshot A。
467
+ 10. 在 Class filter 依次搜索:
468
+ - `Blob`
469
+ - `ArrayBuffer`
470
+ - `HTMLImageElement`
471
+ - `Detached`
472
+ - 上传组件名,如 `VabUpload`
473
+ 11. 展开可疑对象,在 Retainers 中确认是否仍被已关闭的 Vue 组件、`fileList`、`pasteList` 或 DOM 引用。
474
+
475
+ 页面上快速确认当前 Blob URL 数量时,可在 Console 执行:
476
+
477
+ ```js
478
+ performance.getEntriesByType("resource")
479
+ .map(item => item.name)
480
+ .filter(name => name.startsWith("blob:"))
481
+ ```
482
+
483
+ 注意:Performance Resource Timing 不保证记录所有 Blob,最终结论以 Heap Snapshot 和 Retainers 为准。
484
+
485
+ 通过标准:
486
+
487
+ - C 中 Blob URL 数量能够明显回落,不随循环次数线性累积。
488
+ - 动态上传弹窗关闭后,其 Vue 根实例和根 DOM 可被回收。
489
+ - 异步预览请求在组件销毁后返回时,新建 URL 会立即释放。
490
+ - 下载与打印功能仍可正常打开或保存文件。
491
+
492
+ ## 8. 两小时长稳测试
493
+
494
+ ### 8.1 操作脚本
495
+
496
+ 以 10 分钟为一轮,共执行 12 轮:
497
+
498
+ 1. 普通查询 20 次,其中 5 次快速连点。
499
+ 2. 有数据/空结果切换 5 次。
500
+ 3. 编辑 10 行,每行连续修改 3 次。
501
+ 4. 粘贴 20 行数据并继续修改其中 5 行。
502
+ 5. 新增、删除普通行和树节点各 5 次。
503
+ 6. 上传、预览、删除图片各 5 次。
504
+ 7. 下载、导入结果和打印预览各 2 次。
505
+ 8. 切换 5 个菜单后返回测试页。
506
+
507
+ ### 8.2 每轮记录
508
+
509
+ | 指标 | 工具 | 记录方式 |
510
+ | --- | --- | --- |
511
+ | 标签页内存 | Chrome 任务管理器 | MB |
512
+ | JS heap | Performance Monitor | used/total MB |
513
+ | DOM Nodes | Performance Monitor | 数量 |
514
+ | Event Listeners | Performance Monitor | 数量 |
515
+ | Blob | Heap Snapshot | 数量及 retained size |
516
+ | 表格组件实例 | Heap Snapshot | 数量及 retained size |
517
+ | canceled 请求 | Network | 数量、是否误弹错误 |
518
+
519
+ 具体记录方式:
520
+
521
+ 1. 在 Performance monitor 中将鼠标停到各曲线上,记录本轮结束时数值。
522
+ 2. 每轮结束等待 30 秒,让短期定时器、请求和组件卸载完成。
523
+ 3. 第 2、6、12 轮结束后进入 Memory,点击 **Collect garbage** 两次并拍 Heap Snapshot。
524
+ 4. Chrome 右上角 `⋮` → **More tools** → **Task manager**,找到当前测试页,记录 Memory footprint。
525
+ 5. Network 面板右键请求列表 → **Save all as HAR with content**,每小时保存一次。
526
+ 6. 两小时测试期间不要刷新整个浏览器;只有用例明确要求时才刷新业务页面。
527
+
528
+ ### 8.3 通过标准
529
+
530
+ - 预热后的 JS heap 呈波动平台,而非连续 12 轮单调增长。
531
+ - 强制 GC 后,第 12 轮 heap 不超过第 2 轮基线的 130%。
532
+ - 空结果或关闭页面后,旧表格组件和 Blob 数量能够回落。
533
+ - 无标签页崩溃、页面假死、永久 loading 或连续错误弹窗。
534
+ - 所有最终业务数据与最后一次用户操作一致。
535
+
536
+ 若业务页面本身基线较大,可调整 130% 阈值,但必须在报告中说明原因并附 Heap Snapshot 对比。
537
+
538
+ ## 9. 结果记录表
539
+
540
+ | 用例编号 | 场景 | 结果 | 关键数据 | 证据文件 | 问题单 |
541
+ | --- | --- | --- | --- | --- | --- |
542
+ | DT-01 | 连续查询 100 次 | 待执行 | | | |
543
+ | DT-02 | 有数据/空结果 20 轮 | 待执行 | | | |
544
+ | DT-03 | 乱序响应 | 待执行 | | | |
545
+ | DT-04 | 普通/编辑/树表增删 | 待执行 | | | |
546
+ | AS-01 | 同行连续修改与补存 | 待执行 | | | |
547
+ | AS-02 | 粘贴与失焦竞争 | 待执行 | | | |
548
+ | AS-03 | 20 行队列上限 | 待执行 | | | |
549
+ | AS-04 | 保存中删行 | 待执行 | | | |
550
+ | AS-05 | 保存中关页 | 待执行 | | | |
551
+ | BL-01 | Blob URL 全矩阵 | 待执行 | | | |
552
+ | LS-01 | 两小时长稳 | 待执行 | | | |
553
+
554
+ ## 10. 缺陷记录要求
555
+
556
+ 每个失败项至少包含:
557
+
558
+ - 页面、表单编码、表格字段名和部署版本。
559
+ - 浏览器版本、发生时间和操作步骤。
560
+ - 查询条件、数据量、接口延迟和是否启用分页。
561
+ - Network HAR、控制台日志、截图或录屏。
562
+ - 问题前后的 Heap Snapshot;内存问题补充 Comparison 视图。
563
+ - 当前 `rowIdData`、`fieldSchemaMap`、`refList`、自动保存等待行数。
564
+ - 是否可稳定复现以及最小复现频率。
565
+
566
+ ## 11. 发布准入与回退判定
567
+
568
+ ### 11.1 准入条件
569
+
570
+ 同时满足以下条件后,P0 修改才允许按文件或提交同步到正式源仓:
571
+
572
+ 1. 第 4 节自动化测试全部通过。
573
+ 2. 第 5–7 节专项用例全部通过,无 P0/P1 缺陷。
574
+ 3. 两小时长稳测试通过,内存无单调上涨趋势。
575
+ 4. 生产构建成功,警告与基线相比无本次新增异常。
576
+ 5. 测试证据、构建 Hash 和修改文件清单已归档。
577
+
578
+ ### 11.2 立即停止或回退条件
579
+
580
+ 出现以下任一情况,停止同步或回退本次 P0 修改:
581
+
582
+ - 最后一次查询结果被旧响应覆盖。
583
+ - 自动保存出现并发写入、静默丢失或删除行被重新写回。
584
+ - 关闭页签后仍持续请求、弹窗或持有大批表格实例。
585
+ - Blob、detached DOM 或 JS heap 随循环次数稳定线性增长。
586
+ - 出现新的标签页崩溃、页面假死或不可恢复 loading。
587
+
588
+ ## 12. 测试签字
589
+
590
+ | 角色 | 姓名 | 日期 | 结论 |
591
+ | --- | --- | --- | --- |
592
+ | 开发自测 | | | |
593
+ | 专项测试 | | | |
594
+ | 业务验收 | | | |
595
+ | 发布确认 | | | |