@epxing/designer 0.0.0-stage → 5.3.0-beta.1

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 (491) hide show
  1. package/API.md +159 -0
  2. package/README.md +44 -2
  3. package/dist/_virtual/_plugin-vue_export-helper.js +10 -0
  4. package/dist/_virtual/preload-helper.js +88 -0
  5. package/dist/assets/default-icon-2193FMjv.png +0 -0
  6. package/dist/assets/technology_bg-oWIS2awO.jpg +0 -0
  7. package/dist/assets/theme_black-Ctdygcr4.png +0 -0
  8. package/dist/assets/theme_technology-DJk-2e7g.png +0 -0
  9. package/dist/assets/theme_white-uMQ6JYml.png +0 -0
  10. package/dist/src/assets/images/dashboard/theme_black.png.js +4 -0
  11. package/dist/src/assets/images/dashboard/theme_technology.png.js +4 -0
  12. package/dist/src/assets/images/dashboard/theme_white.png.js +4 -0
  13. package/dist/src/assets/images/default-icon.png.js +4 -0
  14. package/dist/src/index.js +52 -0
  15. package/dist/src/page-designer/PageConfigPreview.js +101 -0
  16. package/dist/src/page-designer/PageDesigner.js +843 -0
  17. package/dist/src/page-designer/designer.js +1119 -0
  18. package/dist/src/page-designer/index.js +51 -0
  19. package/dist/src/page-designer/mixins/dragSourceMixin.js +94 -0
  20. package/dist/src/page-designer/page-variable-panel/JsonEditor.js +105 -0
  21. package/dist/src/page-designer/page-variable-panel/PageVariablePanel.js +938 -0
  22. package/dist/src/page-designer/page-variable-panel/index.js +6 -0
  23. package/dist/src/page-designer/page-variable-panel/jsonlint.js +229 -0
  24. package/dist/src/page-designer/previews/add-form/Preview.js +7 -0
  25. package/dist/src/page-designer/previews/add-form/Preview.vue.js +328 -0
  26. package/dist/src/page-designer/previews/add-form-item/Preview.js +193 -0
  27. package/dist/src/page-designer/previews/button/Preview.js +29 -0
  28. package/dist/src/page-designer/previews/card/Preview.js +86 -0
  29. package/dist/src/page-designer/previews/carousel/CarouselItemPreview.js +32 -0
  30. package/dist/src/page-designer/previews/carousel/Preview.js +60 -0
  31. package/dist/src/page-designer/previews/collapse/CollapseItemPreview.js +117 -0
  32. package/dist/src/page-designer/previews/collapse/Preview.js +34 -0
  33. package/dist/src/page-designer/previews/dropdown/Preview.js +67 -0
  34. package/dist/src/page-designer/previews/entity-list/Preview.js +521 -0
  35. package/dist/src/page-designer/previews/entity-sub-list/Preview.js +351 -0
  36. package/dist/src/page-designer/previews/entity-virtual-list/Preview.js +10 -0
  37. package/dist/src/page-designer/previews/form-field/preview/Checkbox.js +90 -0
  38. package/dist/src/page-designer/previews/form-field/preview/Date.js +76 -0
  39. package/dist/src/page-designer/previews/form-field/preview/Input.js +73 -0
  40. package/dist/src/page-designer/previews/form-field/preview/InputNumber.js +73 -0
  41. package/dist/src/page-designer/previews/form-field/preview/Object.js +76 -0
  42. package/dist/src/page-designer/previews/form-field/preview/Radio.js +145 -0
  43. package/dist/src/page-designer/previews/form-field/preview/Select.js +77 -0
  44. package/dist/src/page-designer/previews/form-field/preview/Textarea.js +77 -0
  45. package/dist/src/page-designer/previews/grid/Preview.js +138 -0
  46. package/dist/src/page-designer/previews/html/Preview.js +17 -0
  47. package/dist/src/page-designer/previews/icon/Preview.js +19 -0
  48. package/dist/src/page-designer/previews/image/Preview.js +35 -0
  49. package/dist/src/page-designer/previews/index.js +73 -0
  50. package/dist/src/page-designer/previews/layout/ColumnPreview.js +46 -0
  51. package/dist/src/page-designer/previews/layout/Preview.js +109 -0
  52. package/dist/src/page-designer/previews/num/Preview.js +131 -0
  53. package/dist/src/page-designer/previews/page-tabs/Preview.js +74 -0
  54. package/dist/src/page-designer/previews/step/Preview.js +206 -0
  55. package/dist/src/page-designer/previews/tabs/Preview.js +94 -0
  56. package/dist/src/page-designer/previews/tabs/tab-pane/Preview.js +32 -0
  57. package/dist/src/page-designer/previews/text/Preview.js +37 -0
  58. package/dist/src/page-designer/previews/text-editor/Preview.js +22 -0
  59. package/dist/src/page-designer/previews/video/Preview.js +9 -0
  60. package/dist/src/page-designer/setting-panel/Advance.js +280 -0
  61. package/dist/src/page-designer/setting-panel/CodeEditor.js +93 -0
  62. package/dist/src/page-designer/setting-panel/Property.js +164 -0
  63. package/dist/src/page-designer/setting-panel/Setting.js +295 -0
  64. package/dist/src/page-designer/setting-panel/Style.js +1590 -0
  65. package/dist/src/page-designer/setting-panel/css-editor/CssEditor.js +97 -0
  66. package/dist/src/page-designer/setting-panel/css-editor/css-hint.js +83 -0
  67. package/dist/src/page-designer/setting-panel/index.js +10 -0
  68. package/dist/src/page-designer/template-attribute-panel/TemplateAttributePanel.js +486 -0
  69. package/dist/src/page-designer/template-attribute-panel/index.js +4 -0
  70. package/dist/src/page-designer/template-library/Library.js +218 -0
  71. package/dist/src/page-designer/template-library/index.js +4 -0
  72. package/dist/src/page-designer/widget-library/Base.js +169 -0
  73. package/dist/src/page-designer/widget-library/Library.js +212 -0
  74. package/dist/src/page-designer/widget-library/index.js +6 -0
  75. package/dist/src/page-designer/widget-preview/Container.js +79 -0
  76. package/dist/src/page-designer/widget-preview/DragGhost.js +53 -0
  77. package/dist/src/page-designer/widget-preview/DropZoneOverlay.js +41 -0
  78. package/dist/src/page-designer/widget-preview/HoverOverlay.js +60 -0
  79. package/dist/src/page-designer/widget-preview/Mixin.js +259 -0
  80. package/dist/src/page-designer/widget-preview/Placeholder.js +27 -0
  81. package/dist/src/page-designer/widget-preview/Preview.js +276 -0
  82. package/dist/src/page-designer/widget-preview/PreviewItem.js +82 -0
  83. package/dist/src/page-designer/widget-preview/SelectedOverlay.js +331 -0
  84. package/dist/src/page-designer/widget-preview/Template.js +65 -0
  85. package/dist/src/page-designer/widget-preview/WidgetWrapper.js +169 -0
  86. package/dist/src/page-designer/widget-preview/directive.js +158 -0
  87. package/dist/src/page-designer/widget-preview/dropPosition.js +49 -0
  88. package/dist/src/page-designer/widget-preview/index.js +22 -0
  89. package/dist/src/page-designer/widget-preview/overlayPositionMixin.js +86 -0
  90. package/dist/src/page-designer/widget-preview/resolvePreviewName.js +31 -0
  91. package/dist/src/page-designer/widget-tree/Item.js +579 -0
  92. package/dist/src/page-designer/widget-tree/Tree.js +854 -0
  93. package/dist/src/page-designer/widget-tree/index.js +6 -0
  94. package/dist/src/visual/AddForm.js +171 -0
  95. package/dist/src/visual/AddFormItem.js +479 -0
  96. package/dist/src/visual/AppIndex.js +242 -0
  97. package/dist/src/visual/ApplyForm.js +134 -0
  98. package/dist/src/visual/AttributeList.js +343 -0
  99. package/dist/src/visual/BasePage.js +76 -0
  100. package/dist/src/visual/Button.js +4 -0
  101. package/dist/src/visual/Button.vue.js +89 -0
  102. package/dist/src/visual/CardNum.js +73 -0
  103. package/dist/src/visual/CategoryList.js +568 -0
  104. package/dist/src/visual/Chart.js +26 -0
  105. package/dist/src/visual/ChartNew.js +4 -0
  106. package/dist/src/visual/ChartNew.vue.js +54 -0
  107. package/dist/src/visual/CheckForm.js +109 -0
  108. package/dist/src/visual/ClientList.js +40 -0
  109. package/dist/src/visual/CodeManage.js +112 -0
  110. package/dist/src/visual/Component.js +5 -0
  111. package/dist/src/visual/Component.vue.js +1332 -0
  112. package/dist/src/visual/ComponentList.js +279 -0
  113. package/dist/src/visual/Config.js +7 -0
  114. package/dist/src/visual/Config.vue.js +862 -0
  115. package/dist/src/visual/ConfigItem.js +7 -0
  116. package/dist/src/visual/ConfigItem.vue.js +192 -0
  117. package/dist/src/visual/ConfigSelectItems.js +7 -0
  118. package/dist/src/visual/ConfigSelectItems.vue.js +260 -0
  119. package/dist/src/visual/CreatePage.js +388 -0
  120. package/dist/src/visual/DashboardDiv.js +57 -0
  121. package/dist/src/visual/DashboardTabs.js +8 -0
  122. package/dist/src/visual/DashboardTabs.vue.js +127 -0
  123. package/dist/src/visual/DashboardWidget.js +4 -0
  124. package/dist/src/visual/DashboardWidget.vue.js +62 -0
  125. package/dist/src/visual/DblogList.js +81 -0
  126. package/dist/src/visual/EntityAddPage.js +48 -0
  127. package/dist/src/visual/EntityApplyPage.js +53 -0
  128. package/dist/src/visual/EntityCardList.js +454 -0
  129. package/dist/src/visual/EntityCheckPage.js +65 -0
  130. package/dist/src/visual/EntityFindPage.js +44 -0
  131. package/dist/src/visual/EntityList.js +5 -0
  132. package/dist/src/visual/EntityList.vue.js +1221 -0
  133. package/dist/src/visual/EntityListPage.js +42 -0
  134. package/dist/src/visual/EntityNoSubmitSubList.js +266 -0
  135. package/dist/src/visual/EntityRightSubList.js +28 -0
  136. package/dist/src/visual/EntitySubAdd.js +9 -0
  137. package/dist/src/visual/EntitySubGridItem.js +65 -0
  138. package/dist/src/visual/EntitySubList.js +433 -0
  139. package/dist/src/visual/EntityTreeFindPage.js +31 -0
  140. package/dist/src/visual/EntityTreeManage.js +48 -0
  141. package/dist/src/visual/EntityTreePage.js +41 -0
  142. package/dist/src/visual/ExcelPreview.js +9 -0
  143. package/dist/src/visual/FormField.js +4 -0
  144. package/dist/src/visual/FormField.vue.js +121 -0
  145. package/dist/src/visual/HeaderNew.js +160 -0
  146. package/dist/src/visual/Html.js +7 -0
  147. package/dist/src/visual/Html.vue.js +109 -0
  148. package/dist/src/visual/Import.js +52 -0
  149. package/dist/src/visual/InterfaceSubList.js +20 -0
  150. package/dist/src/visual/ListFirst.js +703 -0
  151. package/dist/src/visual/MEntityAddPage.js +65 -0
  152. package/dist/src/visual/MEntityList.js +484 -0
  153. package/dist/src/visual/MEntityListPage.js +39 -0
  154. package/dist/src/visual/MEntitySubList.js +236 -0
  155. package/dist/src/visual/MetaList.js +22 -0
  156. package/dist/src/visual/ModuleIndexPage.js +66 -0
  157. package/dist/src/visual/ModuleList.js +46 -0
  158. package/dist/src/visual/NavAddForm.js +172 -0
  159. package/dist/src/visual/NavFormCatalogItem.js +43 -0
  160. package/dist/src/visual/NumItem.js +69 -0
  161. package/dist/src/visual/NumStatistic.js +5 -0
  162. package/dist/src/visual/NumStatistic.vue.js +81 -0
  163. package/dist/src/visual/OrgChart.js +106 -0
  164. package/dist/src/visual/PageCatalog.js +26 -0
  165. package/dist/src/visual/PageConfig.js +222 -0
  166. package/dist/src/visual/PageTabs.js +48 -0
  167. package/dist/src/visual/Progress.js +39 -0
  168. package/dist/src/visual/ProgressItem.js +43 -0
  169. package/dist/src/visual/SystemManager.js +76 -0
  170. package/dist/src/visual/Title.js +44 -0
  171. package/dist/src/visual/TodoList.js +13 -0
  172. package/dist/src/visual/UserFormItem.js +40 -0
  173. package/dist/src/visual/UserManage.js +34 -0
  174. package/dist/src/visual/chart/CircularPie.js +8 -0
  175. package/dist/src/visual/chart/Column.js +69 -0
  176. package/dist/src/visual/chart/HoriColumn.js +8 -0
  177. package/dist/src/visual/chart/Line.js +8 -0
  178. package/dist/src/visual/chart/Pie.js +8 -0
  179. package/dist/src/visual/config/Background.js +525 -0
  180. package/dist/src/visual/config/Chart.js +153 -0
  181. package/dist/src/visual/config/Checkbox.js +62 -0
  182. package/dist/src/visual/config/Color.js +40 -0
  183. package/dist/src/visual/config/DesignReport.js +23 -0
  184. package/dist/src/visual/config/Event.js +303 -0
  185. package/dist/src/visual/config/Field.js +519 -0
  186. package/dist/src/visual/config/Font.js +201 -0
  187. package/dist/src/visual/config/FormItem.js +22 -0
  188. package/dist/src/visual/config/Function.js +113 -0
  189. package/dist/src/visual/config/Html.js +110 -0
  190. package/dist/src/visual/config/Image.js +101 -0
  191. package/dist/src/visual/config/Input.js +176 -0
  192. package/dist/src/visual/config/Input.vue.js +479 -0
  193. package/dist/src/visual/config/LazyDialog.js +40 -0
  194. package/dist/src/visual/config/List.js +64 -0
  195. package/dist/src/visual/config/ListField.js +2079 -0
  196. package/dist/src/visual/config/MField.js +732 -0
  197. package/dist/src/visual/config/Number.js +36 -0
  198. package/dist/src/visual/config/Object.js +167 -0
  199. package/dist/src/visual/config/Operate.js +1108 -0
  200. package/dist/src/visual/config/OperateItem.js +1185 -0
  201. package/dist/src/visual/config/Options.js +7 -0
  202. package/dist/src/visual/config/Options.vue.js +278 -0
  203. package/dist/src/visual/config/OrderField.js +504 -0
  204. package/dist/src/visual/config/Page.js +75 -0
  205. package/dist/src/visual/config/Params.js +352 -0
  206. package/dist/src/visual/config/Radio.js +126 -0
  207. package/dist/src/visual/config/Row.js +103 -0
  208. package/dist/src/visual/config/Scope.js +349 -0
  209. package/dist/src/visual/config/Select.js +94 -0
  210. package/dist/src/visual/config/Switch.js +36 -0
  211. package/dist/src/visual/config/Textarea.js +174 -0
  212. package/dist/src/visual/config/Textarea.vue.js +507 -0
  213. package/dist/src/visual/config/Tree.js +137 -0
  214. package/dist/src/visual/config/remote-cache.js +29 -0
  215. package/dist/src/visual/config/show-condition.js +19 -0
  216. package/dist/src/visual/config/variable-sources.js +26 -0
  217. package/dist/src/visual/config/wait-ref.js +18 -0
  218. package/dist/src/visual/config-page/ComponentLibrary.js +169 -0
  219. package/dist/src/visual/config-page/ComponentLibraryDialog.js +249 -0
  220. package/dist/src/visual/config-page/ComponentList.js +8 -0
  221. package/dist/src/visual/config-page/ComponentList.vue.js +292 -0
  222. package/dist/src/visual/config-page/ComponentPreview.js +7 -0
  223. package/dist/src/visual/config-page/ComponentPreview.vue.js +151 -0
  224. package/dist/src/visual/config-page/ConfigOption.js +12 -0
  225. package/dist/src/visual/config-page/ConfigPanel.js +301 -0
  226. package/dist/src/visual/config-page/Dashboard.js +2159 -0
  227. package/dist/src/visual/config-page/DashboardDesign.js +605 -0
  228. package/dist/src/visual/config-page/DashboardGlobalConfig.js +5 -0
  229. package/dist/src/visual/config-page/DashboardGlobalConfig.vue.js +292 -0
  230. package/dist/src/visual/config-page/DashboardMobile.js +1114 -0
  231. package/dist/src/visual/config-page/DashboardSetting.js +85 -0
  232. package/dist/src/visual/config-page/PagePreview.js +7 -0
  233. package/dist/src/visual/config-page/PagePreview.vue.js +72 -0
  234. package/dist/src/visual/config-page/StyleConfig.js +978 -0
  235. package/dist/src/visual/config-page/VisualConfigPage.js +644 -0
  236. package/dist/src/visual/config-page/dashboard-theme-setting/Background.js +179 -0
  237. package/dist/src/visual/config-page/dashboard-theme-setting/Border.js +313 -0
  238. package/dist/src/visual/config-page/dashboard-theme-setting/Font.js +191 -0
  239. package/dist/src/visual/config-page/dashboard-theme-setting/Index.js +544 -0
  240. package/dist/src/visual/config-page/dashboard-theme-setting/Shadow.js +173 -0
  241. package/dist/src/visual/config-page/index.js +89 -0
  242. package/dist/src/visual/index.js +150 -0
  243. package/dist/src/visual/mixins/innerGridMixin.js +121 -0
  244. package/dist/src/visual/search/Filter.js +48 -0
  245. package/dist/src/visual/step/Index.js +7 -0
  246. package/dist/src/visual/step/Index.vue.js +485 -0
  247. package/dist/src/visual/step/Item.js +138 -0
  248. package/dist/src/visual/widgets/CardFormItemVisual.js +44 -0
  249. package/dist/src/visual/widgets/CarouselVisual.js +7 -0
  250. package/dist/src/visual/widgets/CarouselVisual.vue.js +303 -0
  251. package/dist/src/visual/widgets/CollapseVisual.js +7 -0
  252. package/dist/src/visual/widgets/CollapseVisual.vue.js +202 -0
  253. package/dist/src/visual/widgets/DropdownVisual.js +7 -0
  254. package/dist/src/visual/widgets/DropdownVisual.vue.js +955 -0
  255. package/dist/src/visual/widgets/LayoutConfig.js +7 -0
  256. package/dist/src/visual/widgets/LayoutConfig.vue.js +168 -0
  257. package/dist/src/visual/widgets/ListVisual.js +348 -0
  258. package/dist/src/visual/widgets/MEntityListFindVisual.js +75 -0
  259. package/dist/src/visual/widgets/ProcessFormItemVisual.js +4 -0
  260. package/dist/src/visual/widgets/ProcessFormItemVisual.vue.js +45 -0
  261. package/dist/src/visual/widgets/TabsConfig.js +7 -0
  262. package/dist/src/visual/widgets/TabsConfig.vue.js +343 -0
  263. package/dist/style.css +9907 -0
  264. package/package.json +103 -3
  265. package/src/index.js +27 -0
  266. package/src/page-designer/PageConfigPreview.vue +103 -0
  267. package/src/page-designer/PageDesigner.vue +1017 -0
  268. package/src/page-designer/designer.js +1299 -0
  269. package/src/page-designer/index.js +38 -0
  270. package/src/page-designer/mixins/dragSourceMixin.js +113 -0
  271. package/src/page-designer/page-variable-panel/JsonEditor.vue +109 -0
  272. package/src/page-designer/page-variable-panel/PageVariablePanel.vue +781 -0
  273. package/src/page-designer/page-variable-panel/index.js +6 -0
  274. package/src/page-designer/page-variable-panel/jsonlint.js +2 -0
  275. package/src/page-designer/previews/add-form/Preview.vue +331 -0
  276. package/src/page-designer/previews/add-form-item/Preview.vue +167 -0
  277. package/src/page-designer/previews/button/Preview.vue +27 -0
  278. package/src/page-designer/previews/card/Preview.vue +78 -0
  279. package/src/page-designer/previews/carousel/CarouselItemPreview.vue +32 -0
  280. package/src/page-designer/previews/carousel/Preview.vue +36 -0
  281. package/src/page-designer/previews/collapse/CollapseItemPreview.vue +136 -0
  282. package/src/page-designer/previews/collapse/Preview.vue +28 -0
  283. package/src/page-designer/previews/dropdown/Preview.vue +21 -0
  284. package/src/page-designer/previews/entity-list/Preview.vue +382 -0
  285. package/src/page-designer/previews/entity-sub-list/Preview.vue +283 -0
  286. package/src/page-designer/previews/entity-virtual-list/Preview.vue +14 -0
  287. package/src/page-designer/previews/form-field/preview/Checkbox.vue +57 -0
  288. package/src/page-designer/previews/form-field/preview/Date.vue +56 -0
  289. package/src/page-designer/previews/form-field/preview/Input.vue +53 -0
  290. package/src/page-designer/previews/form-field/preview/InputNumber.vue +53 -0
  291. package/src/page-designer/previews/form-field/preview/Object.vue +53 -0
  292. package/src/page-designer/previews/form-field/preview/Radio.vue +69 -0
  293. package/src/page-designer/previews/form-field/preview/Select.vue +55 -0
  294. package/src/page-designer/previews/form-field/preview/Textarea.vue +57 -0
  295. package/src/page-designer/previews/grid/Preview.vue +156 -0
  296. package/src/page-designer/previews/html/Preview.vue +11 -0
  297. package/src/page-designer/previews/icon/Preview.vue +12 -0
  298. package/src/page-designer/previews/image/Preview.vue +37 -0
  299. package/src/page-designer/previews/index.js +74 -0
  300. package/src/page-designer/previews/layout/ColumnPreview.vue +89 -0
  301. package/src/page-designer/previews/layout/Preview.vue +96 -0
  302. package/src/page-designer/previews/num/Preview.vue +100 -0
  303. package/src/page-designer/previews/page-tabs/Preview.vue +53 -0
  304. package/src/page-designer/previews/step/Preview.vue +190 -0
  305. package/src/page-designer/previews/tabs/Preview.vue +66 -0
  306. package/src/page-designer/previews/tabs/tab-pane/Preview.vue +32 -0
  307. package/src/page-designer/previews/text/Preview.vue +26 -0
  308. package/src/page-designer/previews/text-editor/Preview.vue +14 -0
  309. package/src/page-designer/previews/video/Preview.vue +9 -0
  310. package/src/page-designer/setting-panel/Advance.vue +175 -0
  311. package/src/page-designer/setting-panel/CodeEditor.vue +88 -0
  312. package/src/page-designer/setting-panel/Property.vue +163 -0
  313. package/src/page-designer/setting-panel/Setting.vue +271 -0
  314. package/src/page-designer/setting-panel/Style.vue +1096 -0
  315. package/src/page-designer/setting-panel/css-editor/CssEditor.vue +93 -0
  316. package/src/page-designer/setting-panel/css-editor/css-hint.js +58 -0
  317. package/src/page-designer/setting-panel/index.js +10 -0
  318. package/src/page-designer/template-attribute-panel/TemplateAttributePanel.vue +383 -0
  319. package/src/page-designer/template-attribute-panel/index.js +2 -0
  320. package/src/page-designer/template-library/Library.vue +153 -0
  321. package/src/page-designer/template-library/index.js +4 -0
  322. package/src/page-designer/widget-library/Base.vue +156 -0
  323. package/src/page-designer/widget-library/Library.vue +282 -0
  324. package/src/page-designer/widget-library/index.js +6 -0
  325. package/src/page-designer/widget-preview/Container.vue +89 -0
  326. package/src/page-designer/widget-preview/DragGhost.vue +83 -0
  327. package/src/page-designer/widget-preview/DropZoneOverlay.vue +51 -0
  328. package/src/page-designer/widget-preview/HoverOverlay.vue +85 -0
  329. package/src/page-designer/widget-preview/Mixin.js +285 -0
  330. package/src/page-designer/widget-preview/Placeholder.vue +22 -0
  331. package/src/page-designer/widget-preview/Preview.vue +322 -0
  332. package/src/page-designer/widget-preview/PreviewItem.vue +162 -0
  333. package/src/page-designer/widget-preview/SelectedOverlay.vue +340 -0
  334. package/src/page-designer/widget-preview/Template.vue +77 -0
  335. package/src/page-designer/widget-preview/WidgetWrapper.vue +197 -0
  336. package/src/page-designer/widget-preview/directive.js +258 -0
  337. package/src/page-designer/widget-preview/dropPosition.js +51 -0
  338. package/src/page-designer/widget-preview/index.js +23 -0
  339. package/src/page-designer/widget-preview/overlayPositionMixin.js +88 -0
  340. package/src/page-designer/widget-preview/resolvePreviewName.js +33 -0
  341. package/src/page-designer/widget-tree/Item.vue +719 -0
  342. package/src/page-designer/widget-tree/Tree.vue +995 -0
  343. package/src/page-designer/widget-tree/index.js +6 -0
  344. package/src/visual/AddForm.vue +172 -0
  345. package/src/visual/AddFormItem.vue +482 -0
  346. package/src/visual/AppIndex.vue +245 -0
  347. package/src/visual/ApplyForm.vue +140 -0
  348. package/src/visual/AttributeList.vue +344 -0
  349. package/src/visual/BasePage.vue +76 -0
  350. package/src/visual/Button.vue +80 -0
  351. package/src/visual/CardNum.vue +73 -0
  352. package/src/visual/CategoryList.vue +563 -0
  353. package/src/visual/Chart.vue +29 -0
  354. package/src/visual/ChartNew.vue +49 -0
  355. package/src/visual/CheckForm.vue +106 -0
  356. package/src/visual/ClientList.vue +42 -0
  357. package/src/visual/CodeManage.vue +116 -0
  358. package/src/visual/Component.vue +1342 -0
  359. package/src/visual/ComponentList.vue +280 -0
  360. package/src/visual/Config.vue +881 -0
  361. package/src/visual/ConfigItem.vue +218 -0
  362. package/src/visual/ConfigSelectItems.vue +445 -0
  363. package/src/visual/CreatePage.vue +389 -0
  364. package/src/visual/DashboardDiv.vue +197 -0
  365. package/src/visual/DashboardTabs.vue +118 -0
  366. package/src/visual/DashboardWidget.vue +55 -0
  367. package/src/visual/DblogList.vue +84 -0
  368. package/src/visual/EntityAddPage.vue +52 -0
  369. package/src/visual/EntityApplyPage.vue +57 -0
  370. package/src/visual/EntityCardList.vue +449 -0
  371. package/src/visual/EntityCheckPage.vue +69 -0
  372. package/src/visual/EntityFindPage.vue +55 -0
  373. package/src/visual/EntityList.vue +838 -0
  374. package/src/visual/EntityListPage.vue +97 -0
  375. package/src/visual/EntityNoSubmitSubList.vue +273 -0
  376. package/src/visual/EntityRightSubList.vue +32 -0
  377. package/src/visual/EntitySubAdd.vue +11 -0
  378. package/src/visual/EntitySubGridItem.vue +67 -0
  379. package/src/visual/EntitySubList.vue +440 -0
  380. package/src/visual/EntityTreeFindPage.vue +36 -0
  381. package/src/visual/EntityTreeManage.vue +50 -0
  382. package/src/visual/EntityTreePage.vue +45 -0
  383. package/src/visual/ExcelPreview.vue +11 -0
  384. package/src/visual/FormField.vue +113 -0
  385. package/src/visual/HeaderNew.vue +176 -0
  386. package/src/visual/Html.vue +104 -0
  387. package/src/visual/Import.vue +55 -0
  388. package/src/visual/InterfaceSubList.vue +23 -0
  389. package/src/visual/ListFirst.vue +614 -0
  390. package/src/visual/MEntityAddPage.vue +71 -0
  391. package/src/visual/MEntityList.vue +488 -0
  392. package/src/visual/MEntityListPage.vue +46 -0
  393. package/src/visual/MEntitySubList.vue +237 -0
  394. package/src/visual/MetaList.vue +24 -0
  395. package/src/visual/ModuleIndexPage.vue +70 -0
  396. package/src/visual/ModuleList.vue +46 -0
  397. package/src/visual/NavAddForm.vue +177 -0
  398. package/src/visual/NavFormCatalogItem.vue +47 -0
  399. package/src/visual/NumItem.vue +69 -0
  400. package/src/visual/NumStatistic.vue +242 -0
  401. package/src/visual/OrgChart.vue +113 -0
  402. package/src/visual/PageCatalog.vue +26 -0
  403. package/src/visual/PageConfig.vue +278 -0
  404. package/src/visual/PageTabs.vue +55 -0
  405. package/src/visual/Progress.vue +39 -0
  406. package/src/visual/ProgressItem.vue +43 -0
  407. package/src/visual/SystemManager.vue +80 -0
  408. package/src/visual/Title.vue +44 -0
  409. package/src/visual/TodoList.vue +18 -0
  410. package/src/visual/UserFormItem.vue +49 -0
  411. package/src/visual/UserManage.vue +36 -0
  412. package/src/visual/chart/CircularPie.vue +7 -0
  413. package/src/visual/chart/Column.vue +73 -0
  414. package/src/visual/chart/HoriColumn.vue +7 -0
  415. package/src/visual/chart/Line.vue +7 -0
  416. package/src/visual/chart/Pie.vue +7 -0
  417. package/src/visual/config/Background.vue +398 -0
  418. package/src/visual/config/Chart.vue +139 -0
  419. package/src/visual/config/Checkbox.vue +64 -0
  420. package/src/visual/config/Color.vue +40 -0
  421. package/src/visual/config/DesignReport.vue +20 -0
  422. package/src/visual/config/Event.vue +220 -0
  423. package/src/visual/config/Field.vue +597 -0
  424. package/src/visual/config/Font.vue +149 -0
  425. package/src/visual/config/FormItem.vue +25 -0
  426. package/src/visual/config/Function.vue +78 -0
  427. package/src/visual/config/Html.vue +98 -0
  428. package/src/visual/config/Image.vue +132 -0
  429. package/src/visual/config/Input.vue +712 -0
  430. package/src/visual/config/LazyDialog.vue +44 -0
  431. package/src/visual/config/List.vue +68 -0
  432. package/src/visual/config/ListField.vue +1714 -0
  433. package/src/visual/config/MField.vue +601 -0
  434. package/src/visual/config/Number.vue +41 -0
  435. package/src/visual/config/Object.vue +177 -0
  436. package/src/visual/config/Operate.vue +1083 -0
  437. package/src/visual/config/OperateItem.vue +917 -0
  438. package/src/visual/config/Options.vue +330 -0
  439. package/src/visual/config/OrderField.vue +587 -0
  440. package/src/visual/config/Page.vue +45 -0
  441. package/src/visual/config/Params.vue +228 -0
  442. package/src/visual/config/Radio.vue +93 -0
  443. package/src/visual/config/Row.vue +78 -0
  444. package/src/visual/config/Scope.vue +363 -0
  445. package/src/visual/config/Select.vue +93 -0
  446. package/src/visual/config/Switch.vue +36 -0
  447. package/src/visual/config/Textarea.vue +754 -0
  448. package/src/visual/config/Tree.vue +135 -0
  449. package/src/visual/config/remote-cache.js +35 -0
  450. package/src/visual/config/show-condition.js +21 -0
  451. package/src/visual/config/variable-sources.js +27 -0
  452. package/src/visual/config/wait-ref.js +17 -0
  453. package/src/visual/config-page/ComponentLibrary.vue +220 -0
  454. package/src/visual/config-page/ComponentLibraryDialog.vue +262 -0
  455. package/src/visual/config-page/ComponentList.vue +580 -0
  456. package/src/visual/config-page/ComponentPreview.vue +206 -0
  457. package/src/visual/config-page/ConfigOption.vue +16 -0
  458. package/src/visual/config-page/ConfigPanel.vue +301 -0
  459. package/src/visual/config-page/Dashboard.vue +2331 -0
  460. package/src/visual/config-page/DashboardDesign.vue +656 -0
  461. package/src/visual/config-page/DashboardGlobalConfig.vue +158 -0
  462. package/src/visual/config-page/DashboardMobile.vue +1118 -0
  463. package/src/visual/config-page/DashboardSetting.vue +47 -0
  464. package/src/visual/config-page/PagePreview.vue +105 -0
  465. package/src/visual/config-page/StyleConfig.vue +656 -0
  466. package/src/visual/config-page/VisualConfigPage.vue +746 -0
  467. package/src/visual/config-page/dashboard-theme-setting/Background.vue +98 -0
  468. package/src/visual/config-page/dashboard-theme-setting/Border.vue +185 -0
  469. package/src/visual/config-page/dashboard-theme-setting/Font.vue +101 -0
  470. package/src/visual/config-page/dashboard-theme-setting/Index.vue +471 -0
  471. package/src/visual/config-page/dashboard-theme-setting/Shadow.vue +102 -0
  472. package/src/visual/config-page/index.js +93 -0
  473. package/src/visual/index.js +23 -0
  474. package/src/visual/mixins/innerGridMixin.js +128 -0
  475. package/src/visual/search/Filter.vue +50 -0
  476. package/src/visual/step/Index.vue +361 -0
  477. package/src/visual/step/Item.vue +140 -0
  478. package/src/visual/widgets/CardFormItemVisual.vue +46 -0
  479. package/src/visual/widgets/CarouselVisual.vue +291 -0
  480. package/src/visual/widgets/CollapseVisual.vue +203 -0
  481. package/src/visual/widgets/DropdownVisual.vue +541 -0
  482. package/src/visual/widgets/LayoutConfig.vue +186 -0
  483. package/src/visual/widgets/ListVisual.vue +349 -0
  484. package/src/visual/widgets/MEntityListFindVisual.vue +77 -0
  485. package/src/visual/widgets/ProcessFormItemVisual.vue +58 -0
  486. package/src/visual/widgets/TabsConfig.vue +266 -0
  487. package/types/index.d.ts +22 -0
  488. package/types/page-designer.d.ts +3 -0
  489. package/types/visual-component.d.ts +1 -0
  490. package/types/visual-entity-list.d.ts +1 -0
  491. package/types/visual-entity-sub-list.d.ts +1 -0
@@ -0,0 +1,1119 @@
1
+ import { cloneDeep, isEmpty } from "lodash-es";
2
+ import { effectScope, reactive, toRaw, markRaw, watch } from "vue";
3
+ import util from "@epxing/core/src/runtime-utils/util";
4
+ import storage from "@epxing/utils/src/storage";
5
+ const { genId } = util;
6
+ const defaultPageConfig = {};
7
+ function getWidgetSlots(widget) {
8
+ const { slots } = widget || {};
9
+ if (!slots || typeof slots !== "object") return [];
10
+ return Object.keys(slots).filter((name) => slots[name] && slots[name].id).map((name) => ({ name, widget: slots[name] }));
11
+ }
12
+ function getWidgetChildren(widget) {
13
+ const { items = [] } = widget || {};
14
+ return [...items, ...getWidgetSlots(widget).map((slot) => slot.widget)];
15
+ }
16
+ function createDesigner(vueInstance) {
17
+ const designerEvents = /* @__PURE__ */ new Map();
18
+ const widgetInfoIndex = /* @__PURE__ */ new Map();
19
+ const templateIndex = /* @__PURE__ */ new Map();
20
+ let widgetIndex = /* @__PURE__ */ new Map();
21
+ let indexDirty = true;
22
+ const rebuildIndex = () => {
23
+ widgetIndex = /* @__PURE__ */ new Map();
24
+ const walk = (list, parent, slotName) => {
25
+ for (const item of toRaw(list) || []) {
26
+ const raw = toRaw(item);
27
+ if (!raw || !raw.id) continue;
28
+ if (!widgetIndex.has(raw.id)) widgetIndex.set(raw.id, { widget: raw, parent, slotName });
29
+ walk(raw.items, raw, "");
30
+ for (const slot of getWidgetSlots(raw)) walk([slot.widget], raw, slot.name);
31
+ }
32
+ };
33
+ walk(state.widgetList, null, "");
34
+ indexDirty = false;
35
+ };
36
+ const lookup = (id) => {
37
+ if (indexDirty) rebuildIndex();
38
+ return widgetIndex.get(id);
39
+ };
40
+ const asReactive = (obj) => obj ? reactive(obj) : obj;
41
+ let saveTimer = null;
42
+ const scope = effectScope(true);
43
+ const state = reactive({
44
+ version: "2.0",
45
+ mode: "page",
46
+ terminal: "pc",
47
+ page: {},
48
+ // 页面
49
+ widgetList: [],
50
+ // 组件列表
51
+ widgetConfig: {},
52
+ // 组件配置
53
+ templateLibrary: [],
54
+ // 模板列表
55
+ templateAttributeTree: [],
56
+ // 模板配置参数
57
+ pageConfig: {},
58
+ // 页面配置
59
+ allWidgets: [],
60
+ formConfig: { cssCode: "" },
61
+ selectedId: null,
62
+ selectedWidget: null,
63
+ selectedWidgetName: null,
64
+ // 选中组件名称(唯一)
65
+ // 悬浮组件状态
66
+ hoverWidgetId: null,
67
+ hoverWidget: null,
68
+ hoverParentWidget: null,
69
+ // 拖拽时当前悬停的放置目标 { type: 'root' | 'container', widgetId: string | null }
70
+ dragOverTarget: null,
71
+ // 当前放置目标对应的 DOM 元素,用于独立浮层定位
72
+ dragOverTargetElement: null,
73
+ vueInstance,
74
+ formWidget: null,
75
+ // 表单设计容器
76
+ cssClassList: [],
77
+ // 自定义样式列表
78
+ historyData: {
79
+ index: -1,
80
+ // index: 0,
81
+ maxStep: 20,
82
+ steps: []
83
+ },
84
+ initDesigner(resetFormJson) {
85
+ this.widgetList = [];
86
+ this.widgetConfig = {};
87
+ this.pageConfig = cloneDeep(defaultPageConfig);
88
+ if (!resetFormJson) {
89
+ this.initHistoryData();
90
+ }
91
+ },
92
+ clearDesigner(skipHistoryChange) {
93
+ const emptyWidgetListFlag = this.widgetList.length === 0;
94
+ this.widgetList = [];
95
+ this.widgetConfig = {};
96
+ this.selectedId = null;
97
+ this.selectedWidget = {};
98
+ this.pageConfig = cloneDeep(defaultPageConfig);
99
+ if (skipHistoryChange) ;
100
+ else if (!emptyWidgetListFlag) {
101
+ this.emitHistoryChange();
102
+ } else {
103
+ this.saveCurrentHistoryStep();
104
+ }
105
+ },
106
+ initWidgetList(componentList) {
107
+ this.allWidgets = markRaw([...componentList]);
108
+ widgetInfoIndex.clear();
109
+ for (const con of this.allWidgets) {
110
+ if (con && con.CODE) widgetInfoIndex.set(con.CODE, con);
111
+ }
112
+ },
113
+ initTemplateLibrary(templateLibrary) {
114
+ this.templateLibrary = markRaw(templateLibrary || []);
115
+ templateIndex.clear();
116
+ for (const tpl of this.templateLibrary) {
117
+ if (tpl && tpl.ID) templateIndex.set(tpl.ID, tpl);
118
+ }
119
+ },
120
+ setTemplateAttributeTree(data) {
121
+ this.templateAttributeTree = data;
122
+ },
123
+ loadFormJson(page) {
124
+ this.page = page;
125
+ const { isComponent, isTemplate, config: formJson = {} } = page;
126
+ if (isComponent) this.mode = "component";
127
+ if (isTemplate) this.mode = "template";
128
+ let modifiedFlag = false;
129
+ if (formJson) {
130
+ const { items: widgetList = [], itemConfigs: widgetConfig = {}, ...pageConfig } = formJson;
131
+ if (widgetList) {
132
+ this.widgetList = widgetList;
133
+ this.widgetConfig = widgetConfig;
134
+ modifiedFlag = true;
135
+ }
136
+ if (pageConfig) {
137
+ this.pageConfig = { ...pageConfig };
138
+ modifiedFlag = true;
139
+ }
140
+ if (pageConfig.version !== this.version) {
141
+ this.upgradePageConfig();
142
+ this.upgradeWidgetConfig();
143
+ }
144
+ }
145
+ this.initHistoryData();
146
+ if (modifiedFlag) {
147
+ this.emitEvent("form-json-imported", []);
148
+ }
149
+ return modifiedFlag;
150
+ },
151
+ setSelected(selected) {
152
+ if (!selected) {
153
+ this.clearSelected();
154
+ return;
155
+ }
156
+ this.selectedWidget = selected;
157
+ if (selected.id) {
158
+ this.selectedId = selected.id;
159
+ }
160
+ },
161
+ // 根据组件 id 设置悬浮组件
162
+ setHoverById(id) {
163
+ if (!id) {
164
+ this.clearHover();
165
+ return;
166
+ }
167
+ const widget = this.getWidgetItemById(id);
168
+ if (!widget) {
169
+ this.clearHover();
170
+ return;
171
+ }
172
+ const parentWidget = this.findParentWidget(id);
173
+ this.hoverWidgetId = id;
174
+ this.hoverWidget = widget;
175
+ this.hoverParentWidget = parentWidget || null;
176
+ this.emitEvent("hover-change", {
177
+ widget,
178
+ parentWidget: this.hoverParentWidget
179
+ });
180
+ },
181
+ // 清理悬浮组件状态
182
+ clearHover() {
183
+ this.hoverWidgetId = null;
184
+ this.hoverWidget = null;
185
+ this.hoverParentWidget = null;
186
+ this.emitEvent("hover-change", {
187
+ widget: null,
188
+ parentWidget: null
189
+ });
190
+ },
191
+ setDragOverTarget(target) {
192
+ this.dragOverTarget = target;
193
+ },
194
+ setDragOverTargetElement(el) {
195
+ this.dragOverTargetElement = el;
196
+ },
197
+ clearDragOverTarget() {
198
+ this.dragOverTarget = null;
199
+ this.dragOverTargetElement = null;
200
+ },
201
+ // 拖拽插入位置线 { top, left, width } 视口坐标,用于 fixed 定位
202
+ dragInsertLine: null,
203
+ setDragInsertLine(rect) {
204
+ this.dragInsertLine = rect;
205
+ },
206
+ clearDragInsertLine() {
207
+ this.dragInsertLine = null;
208
+ },
209
+ // 预览区域拖拽状态(用于同步到大纲树)
210
+ previewDragTarget: null,
211
+ // { widgetId, index, position }
212
+ previewDragTargetThrottle: null,
213
+ // 节流定时器
214
+ setPreviewDragTarget(target) {
215
+ const current = this.previewDragTarget;
216
+ const isSame = current && target && current.widgetId === target.widgetId && current.index === target.index && current.position === target.position;
217
+ if (isSame) return;
218
+ if (this.previewDragTargetThrottle) {
219
+ clearTimeout(this.previewDragTargetThrottle);
220
+ }
221
+ this.previewDragTargetThrottle = setTimeout(() => {
222
+ this.previewDragTarget = target;
223
+ this.previewDragTargetThrottle = null;
224
+ }, 16);
225
+ },
226
+ clearPreviewDragTarget() {
227
+ if (this.previewDragTargetThrottle) {
228
+ clearTimeout(this.previewDragTargetThrottle);
229
+ this.previewDragTargetThrottle = null;
230
+ }
231
+ this.previewDragTarget = null;
232
+ },
233
+ // 统一的拖拽状态管理
234
+ dragState: {
235
+ isDragging: false,
236
+ // 是否正在拖拽
237
+ isNativeDragging: false,
238
+ // 是否是原生 HTML5 拖拽
239
+ dragSource: null,
240
+ // 拖拽来源:'library' | 'preview' | 'template' | 'tree'
241
+ dragData: null,
242
+ // 拖拽数据
243
+ ghostVisible: false,
244
+ // 拖拽悬浮窗是否可见
245
+ ghostTitle: "",
246
+ // 悬浮窗标题
247
+ ghostIcon: "",
248
+ // 悬浮窗图标
249
+ ghostPosition: { x: 0, y: 0 }
250
+ // 悬浮窗位置
251
+ },
252
+ // 开始拖拽
253
+ startDrag(options = {}) {
254
+ const { source, data, title, icon, x, y, isNative = false } = options;
255
+ this.dragState.isDragging = true;
256
+ this.dragState.isNativeDragging = isNative;
257
+ this.dragState.dragSource = source;
258
+ this.dragState.dragData = data;
259
+ this.dragState.ghostVisible = true;
260
+ this.dragState.ghostTitle = title || "";
261
+ this.dragState.ghostIcon = icon || "";
262
+ this.dragState.ghostPosition = { x: x || 0, y: y || 0 };
263
+ if (source === "preview" && this.vueInstance) {
264
+ this.emitEvent("close-left-panel");
265
+ }
266
+ this.emitEvent("drag-state-change", { ...this.dragState });
267
+ },
268
+ // 更新拖拽悬浮窗位置
269
+ updateDragGhostPosition(x, y) {
270
+ if (this.dragState.isDragging) {
271
+ this.dragState.ghostPosition = { x, y };
272
+ this.emitEvent("drag-ghost-move", { x, y });
273
+ }
274
+ },
275
+ // 结束拖拽
276
+ endDrag() {
277
+ this.dragState.isDragging = false;
278
+ this.dragState.isNativeDragging = false;
279
+ this.dragState.dragSource = null;
280
+ this.dragState.dragData = null;
281
+ this.dragState.ghostVisible = false;
282
+ this.dragState.ghostTitle = "";
283
+ this.dragState.ghostIcon = "";
284
+ this.dragState.ghostPosition = { x: 0, y: 0 };
285
+ this.clearDragOverTarget();
286
+ this.clearDragInsertLine();
287
+ this.clearPreviewDragTarget();
288
+ this.emitEvent("drag-state-change", { ...this.dragState });
289
+ },
290
+ // 获取当前拖拽状态
291
+ getDragState() {
292
+ return { ...this.dragState };
293
+ },
294
+ // ========== 统一的拖拽处理方法 ==========
295
+ /**
296
+ * 解析拖拽数据
297
+ * @param {DataTransfer} dataTransfer - 拖拽事件的 dataTransfer 对象
298
+ * @returns {Object|null} 解析后的拖拽数据 { type, payload }
299
+ */
300
+ parseDragData(dataTransfer) {
301
+ if (!dataTransfer || !dataTransfer.types || !dataTransfer.types.includes("text/plain")) {
302
+ return null;
303
+ }
304
+ try {
305
+ const raw = dataTransfer.getData("text/plain");
306
+ if (!raw) return null;
307
+ if (raw.startsWith("page-designer-widget:")) {
308
+ const payload = JSON.parse(raw.slice("page-designer-widget:".length));
309
+ return { type: "library", payload };
310
+ }
311
+ if (raw.startsWith("page-designer-template:")) {
312
+ const payload = JSON.parse(raw.slice("page-designer-template:".length));
313
+ return { type: "template", payload };
314
+ }
315
+ const data = JSON.parse(raw);
316
+ if (data && data.type === "widget-reorder") {
317
+ return { type: "reorder", payload: data };
318
+ }
319
+ return null;
320
+ } catch (e) {
321
+ return null;
322
+ }
323
+ },
324
+ /**
325
+ * 处理拖拽放置
326
+ * @param {Object} options - 放置选项
327
+ * @param {DataTransfer} options.dataTransfer - 拖拽数据
328
+ * @param {Object} options.target - 放置目标 { type: 'root'|'container'|'slot', widgetId, index, slotName }
329
+ * @returns {boolean} 是否成功处理
330
+ */
331
+ handleDrop(options = {}) {
332
+ const { dataTransfer, target } = options;
333
+ if (!dataTransfer || !target) {
334
+ return false;
335
+ }
336
+ const dragData = this.parseDragData(dataTransfer);
337
+ if (!dragData) {
338
+ return false;
339
+ }
340
+ const { type, payload } = dragData;
341
+ switch (type) {
342
+ case "library":
343
+ return this.handleLibraryDrop(payload, target);
344
+ case "template":
345
+ return this.handleTemplateDrop(payload, target);
346
+ case "reorder":
347
+ return this.handleReorderDrop(payload, target);
348
+ default:
349
+ return false;
350
+ }
351
+ },
352
+ /**
353
+ * 处理组件库拖拽放置
354
+ * @param {Object} payload - 组件数据 { code, title, custom }
355
+ * @param {Object} target - 放置目标
356
+ */
357
+ handleLibraryDrop(payload, target) {
358
+ const { code, title, custom } = payload;
359
+ if (!code) return false;
360
+ const widgetInfo = this.getWidgetByType(code) || {};
361
+ const widget = {
362
+ id: this.genId(code),
363
+ contentType: code,
364
+ title: title || widgetInfo.TITLE
365
+ };
366
+ if (custom) widget.type = "custom";
367
+ if (widgetInfo.CODE === "chart") {
368
+ this.updateWidgetConfig(widget.id, { metaId: this.page.metaId });
369
+ }
370
+ this.insertWidget(widget, target);
371
+ this.setSelected(widget);
372
+ this.emitHistoryChange();
373
+ return true;
374
+ },
375
+ /**
376
+ * 处理模板库拖拽放置
377
+ * @param {Object} payload - 模板数据 { items, itemConfigs, templateJs }
378
+ * @param {Object} target - 放置目标
379
+ */
380
+ handleTemplateDrop(payload, target) {
381
+ const { items, itemConfigs, templateJs } = payload;
382
+ if (!items || !items.length) return false;
383
+ if (target.type === "slot" && items.length > 1) {
384
+ this.vueInstance && this.vueInstance.$message && this.vueInstance.$message("插槽只能放置一个组件");
385
+ return false;
386
+ }
387
+ this.insertWidgets(items, target);
388
+ this.mergeWidgetConfig(itemConfigs);
389
+ if (templateJs) {
390
+ this.mergeTemplateJs(templateJs);
391
+ }
392
+ this.setSelected(items[0]);
393
+ this.emitHistoryChange();
394
+ return true;
395
+ },
396
+ /**
397
+ * 处理组件重排序拖拽放置
398
+ * @param {Object} payload - 拖拽数据 { widgetId, parentWidgetId }
399
+ * @param {Object} target - 放置目标
400
+ */
401
+ handleReorderDrop(payload, target) {
402
+ const { widgetId, parentWidgetId } = payload;
403
+ if (!widgetId) {
404
+ return false;
405
+ }
406
+ const sourceWidget = this.getWidgetItemById(widgetId);
407
+ if (!sourceWidget) {
408
+ return false;
409
+ }
410
+ const sourceParentId = parentWidgetId || null;
411
+ const targetParentId = target.widgetId || null;
412
+ if (target.type === "slot") {
413
+ if (this.isDescendantWidget(target.widgetId, sourceWidget)) return false;
414
+ this.removeWidgetFromParent(sourceWidget);
415
+ if (!this.insertWidget(sourceWidget, target)) return false;
416
+ this.setSelected(sourceWidget);
417
+ this.emitHistoryChange();
418
+ return true;
419
+ }
420
+ if (this.findWidgetSlot(widgetId)) {
421
+ return this.moveWidgetToAnotherContainer(sourceWidget, sourceParentId, target);
422
+ }
423
+ if (sourceParentId === targetParentId) {
424
+ return this.moveWidgetInSameContainer(sourceWidget, target);
425
+ }
426
+ return this.moveWidgetToAnotherContainer(sourceWidget, sourceParentId, target);
427
+ },
428
+ /**
429
+ * 在同一容器内移动组件
430
+ * @param {Object} widget - 要移动的组件
431
+ * @param {Object} target - 目标位置
432
+ */
433
+ moveWidgetInSameContainer(widget, target) {
434
+ const list = target.widgetId ? this.getWidgetItemById(target.widgetId).items : this.widgetList;
435
+ if (!list) {
436
+ return false;
437
+ }
438
+ const sourceIndex = list.findIndex((w) => w.id === widget.id);
439
+ if (sourceIndex === -1) {
440
+ return false;
441
+ }
442
+ let targetIndex = target.index;
443
+ if (targetIndex > sourceIndex) {
444
+ targetIndex = targetIndex + 1;
445
+ }
446
+ if (sourceIndex === targetIndex || sourceIndex + 1 === targetIndex) {
447
+ return false;
448
+ }
449
+ list.splice(sourceIndex, 1);
450
+ if (targetIndex > sourceIndex) {
451
+ targetIndex = targetIndex - 1;
452
+ }
453
+ list.splice(targetIndex, 0, widget);
454
+ if (target.widgetId) {
455
+ this.updateWidget(target.widgetId, { items: [...list] });
456
+ } else {
457
+ this.widgetList = [...list];
458
+ }
459
+ this.setSelected(widget);
460
+ this.emitHistoryChange();
461
+ return true;
462
+ },
463
+ /**
464
+ * 跨容器移动组件
465
+ * @param {Object} widget - 要移动的组件
466
+ * @param {string} sourceParentId - 源容器 ID
467
+ * @param {Object} target - 目标位置
468
+ */
469
+ moveWidgetToAnotherContainer(widget, sourceParentId, target) {
470
+ const sourceSlot = this.findWidgetSlot(widget.id);
471
+ if (sourceSlot) {
472
+ this.clearWidgetSlot(sourceSlot.parent, sourceSlot.slotName);
473
+ } else if (sourceParentId) {
474
+ const sourceParent = this.getWidgetItemById(sourceParentId);
475
+ if (sourceParent && sourceParent.items) {
476
+ const sourceList = [...sourceParent.items];
477
+ const sourceIndex = sourceList.findIndex((w) => w.id === widget.id);
478
+ if (sourceIndex !== -1) {
479
+ sourceList.splice(sourceIndex, 1);
480
+ this.updateWidget(sourceParent.id, { items: sourceList });
481
+ }
482
+ }
483
+ } else {
484
+ const rootList = [...this.widgetList];
485
+ const sourceIndex = rootList.findIndex((w) => w.id === widget.id);
486
+ if (sourceIndex !== -1) {
487
+ rootList.splice(sourceIndex, 1);
488
+ this.widgetList = rootList;
489
+ }
490
+ }
491
+ this.insertWidget(widget, target);
492
+ this.setSelected(widget);
493
+ this.emitHistoryChange();
494
+ return true;
495
+ },
496
+ /**
497
+ * 插入单个组件到指定位置
498
+ * @param {Object} widget - 要插入的组件
499
+ * @param {Object} target - 目标位置 { type: 'root'|'container'|'slot', widgetId, index, slotName }
500
+ */
501
+ insertWidget(widget, target) {
502
+ if (target.type === "slot") {
503
+ return this.setWidgetSlot(target.widgetId, target.slotName, widget);
504
+ }
505
+ if (target.type === "root" || !target.widgetId) {
506
+ const list = [...this.widgetList];
507
+ list.splice(target.index, 0, widget);
508
+ this.widgetList = list;
509
+ } else {
510
+ const container = this.getWidgetItemById(target.widgetId);
511
+ if (!container) return false;
512
+ if (!container.items) {
513
+ this.updateWidget(container.id, { items: [] });
514
+ }
515
+ const list = [...container.items || []];
516
+ list.splice(target.index, 0, widget);
517
+ this.updateWidget(container.id, { items: list });
518
+ }
519
+ return true;
520
+ },
521
+ /**
522
+ * 插入多个组件到指定位置
523
+ * @param {Array} widgets - 要插入的组件数组
524
+ * @param {Object} target - 目标位置
525
+ */
526
+ insertWidgets(widgets, target) {
527
+ if (!widgets || !widgets.length) return false;
528
+ if (target.type === "slot") {
529
+ return this.insertWidget(widgets[0], target);
530
+ }
531
+ if (target.type === "root" || !target.widgetId) {
532
+ const list = [...this.widgetList];
533
+ list.splice(target.index, 0, ...widgets);
534
+ this.widgetList = list;
535
+ } else {
536
+ const container = this.getWidgetItemById(target.widgetId);
537
+ if (!container) return false;
538
+ if (!container.items) {
539
+ this.updateWidget(container.id, { items: [] });
540
+ }
541
+ const list = [...container.items || []];
542
+ list.splice(target.index, 0, ...widgets);
543
+ this.updateWidget(container.id, { items: list });
544
+ }
545
+ return true;
546
+ },
547
+ /**
548
+ * 合并模板 JS 到页面 JS
549
+ * @param {string} templateJs - 模板的 JS 代码
550
+ */
551
+ mergeTemplateJs(templateJs) {
552
+ let { JS = "" } = this.pageConfig;
553
+ const result = JS.match(/export\sfunction\s(\w+)/g);
554
+ const events = [];
555
+ if (result) {
556
+ result.forEach((item) => {
557
+ events.push(item.replace(/export\sfunction\s/, ""));
558
+ });
559
+ }
560
+ const templateJsResult = templateJs.split(/export\s+function\s+/);
561
+ templateJsResult.forEach((item) => {
562
+ const funtionStr = item.replace(/\/\*(\n|.)+?\*\/[\n\s]+$/, "");
563
+ if (funtionStr.replace(/[\n\s]+/g, "").length > 0) {
564
+ const funtionName = funtionStr.split(/\s+\(/)[0];
565
+ if (![...new Set(events)].includes(funtionName)) {
566
+ JS += "export function " + funtionStr.replace(/^\w+/, funtionName);
567
+ }
568
+ }
569
+ });
570
+ this.updatePageConfig({ JS });
571
+ },
572
+ updateSelectedWidgetNameAndLabel(selectedWidget, newName, newLabel) {
573
+ this.selectedWidgetName = newName;
574
+ if (!!newLabel && Object.keys(selectedWidget.options).indexOf("label") > -1) {
575
+ selectedWidget.options.label = newLabel;
576
+ }
577
+ },
578
+ clearSelected() {
579
+ this.selectedId = null;
580
+ this.selectedWidgetName = null;
581
+ this.selectedWidget = null;
582
+ },
583
+ // 检查组件是否可以移动(只有字段组件可以拖入子表单)
584
+ checkWidgetMove(evt) {
585
+ var _a, _b;
586
+ if ((_a = evt.draggedContext) == null ? void 0 : _a.element) {
587
+ const wgCategory = evt.draggedContext.element.category;
588
+ if (((_b = evt.to) == null ? void 0 : _b.className) === "sub-form-table" && wgCategory === "container") {
589
+ return false;
590
+ }
591
+ }
592
+ return true;
593
+ },
594
+ // 检查字段组件是否可以移动
595
+ checkFieldMove(evt) {
596
+ var _a, _b;
597
+ if ((_a = evt.draggedContext) == null ? void 0 : _a.element) {
598
+ const wgType = String(evt.draggedContext.element.type);
599
+ if (((_b = evt.to) == null ? void 0 : _b.className) === "sub-form-table" && wgType === "slot") {
600
+ return false;
601
+ }
602
+ }
603
+ return true;
604
+ },
605
+ // 走索引 O(1);多个同 CODE 取最后一个(与原 forEach 覆盖语义一致),未命中返回 null
606
+ getWidgetByType(typeName, type) {
607
+ if (type === "template") return templateIndex.get(typeName) || null;
608
+ return widgetInfoIndex.get(typeName) || null;
609
+ },
610
+ getContainerByType(typeName) {
611
+ let foundCon = null;
612
+ this.allWidgets.forEach((con) => {
613
+ if (con.CONTAINER === "1" && !!con.type && con.type === typeName) {
614
+ foundCon = con;
615
+ }
616
+ });
617
+ return foundCon;
618
+ },
619
+ getFieldWidgetByType(typeName) {
620
+ let foundWidget = null;
621
+ this.allWidgets.forEach((widget) => {
622
+ if (widget.CONTAINER !== "1" && !!widget.type && widget.type === typeName) {
623
+ foundWidget = widget;
624
+ }
625
+ });
626
+ return foundWidget;
627
+ },
628
+ hasConfig(widget, configName) {
629
+ let originalWidget = null;
630
+ if (widget.CONTAINER === "1") {
631
+ originalWidget = this.getContainerByType(widget.type);
632
+ } else {
633
+ originalWidget = this.getFieldWidgetByType(widget.type);
634
+ }
635
+ if (!originalWidget || !originalWidget.options) {
636
+ return false;
637
+ }
638
+ return Object.keys(originalWidget.options).indexOf(configName) > -1;
639
+ },
640
+ // 走索引;未命中返回 undefined(与原递归实现一致)
641
+ getWidgetItemById(id) {
642
+ const entry = lookup(id);
643
+ return entry ? asReactive(entry.widget) : void 0;
644
+ },
645
+ /**
646
+ * 查找组件所在的插槽位置
647
+ * @param { String } targetId 组件 id
648
+ * @returns { { parent: Object, slotName: String } | null } 不在插槽里返回 null
649
+ */
650
+ findWidgetSlot(targetId) {
651
+ const entry = lookup(targetId);
652
+ return entry && entry.slotName ? { parent: asReactive(entry.parent), slotName: entry.slotName } : null;
653
+ },
654
+ /**
655
+ * 判断 targetId 是否在 widget 自身或其子孙(含插槽)里,
656
+ * 用于阻止把组件拖进自己的插槽造成死循环
657
+ */
658
+ isDescendantWidget(targetId, widget) {
659
+ if (!widget || !targetId) return false;
660
+ if (widget.id === targetId) return true;
661
+ return getWidgetChildren(widget).some((child) => this.isDescendantWidget(targetId, child));
662
+ },
663
+ /**
664
+ * 往插槽里放组件(已有组件时替换)
665
+ */
666
+ setWidgetSlot(ownerId, slotName, widget) {
667
+ const owner = this.getWidgetItemById(ownerId);
668
+ if (!owner || !slotName) return false;
669
+ this.updateWidget(ownerId, { slots: { ...owner.slots || {}, [slotName]: widget } });
670
+ return true;
671
+ },
672
+ /**
673
+ * 清空插槽(插槽全空时把 slots 一起删掉,避免配置里留空对象)
674
+ */
675
+ clearWidgetSlot(owner, slotName) {
676
+ if (!owner || !owner.slots) return false;
677
+ const slots = { ...owner.slots };
678
+ delete slots[slotName];
679
+ this.updateWidget(owner.id, { slots: Object.keys(slots).length > 0 ? slots : null });
680
+ return true;
681
+ },
682
+ /**
683
+ * 把组件从当前位置摘掉(插槽 / 容器 / 根级都支持),用于移动
684
+ */
685
+ removeWidgetFromParent(widget) {
686
+ const slotInfo = this.findWidgetSlot(widget.id);
687
+ if (slotInfo) {
688
+ return this.clearWidgetSlot(slotInfo.parent, slotInfo.slotName);
689
+ }
690
+ const parent = this.findParentWidget(widget.id);
691
+ if (parent && parent.items) {
692
+ const list = [...parent.items];
693
+ const index2 = list.findIndex((item) => item.id === widget.id);
694
+ if (index2 === -1) return false;
695
+ list.splice(index2, 1);
696
+ this.updateWidget(parent.id, { items: list });
697
+ return true;
698
+ }
699
+ const rootList = [...this.widgetList];
700
+ const index = rootList.findIndex((item) => item.id === widget.id);
701
+ if (index === -1) return false;
702
+ rootList.splice(index, 1);
703
+ this.widgetList = rootList;
704
+ return true;
705
+ },
706
+ updateWidget(key, property) {
707
+ const widget = this.getWidgetItemById(key);
708
+ if (widget) {
709
+ for (const key2 in property) {
710
+ if (property[key2] === null) {
711
+ delete widget[key2];
712
+ } else {
713
+ widget[key2] = property[key2];
714
+ }
715
+ }
716
+ }
717
+ },
718
+ updateWidgetConfig(key, configs, type) {
719
+ const property = {};
720
+ for (const configKey in configs) {
721
+ if (configKey.includes("componentName") || configKey === "span" || configKey === "flex") {
722
+ property[configKey.replace("componentName", "title")] = configs[configKey];
723
+ }
724
+ }
725
+ this.updateWidget(key, property);
726
+ const entry = this.widgetConfig[key];
727
+ if (type === "cover" || !entry) {
728
+ const next = { ...configs };
729
+ for (const k in next) {
730
+ if (next[k] === null) delete next[k];
731
+ }
732
+ this.widgetConfig[key] = next;
733
+ return;
734
+ }
735
+ for (const k in configs) {
736
+ if (configs[k] === null) delete entry[k];
737
+ else entry[k] = configs[k];
738
+ }
739
+ },
740
+ // 批量并入多条组件配置(模板拖入 / 复制 / 拆分模板),逐 key 新增而不整体替换 widgetConfig
741
+ mergeWidgetConfig(configs) {
742
+ for (const key in configs) {
743
+ if (configs[key] !== void 0) this.widgetConfig[key] = configs[key];
744
+ }
745
+ },
746
+ updatePageConfig(configs) {
747
+ this.pageConfig = { ...this.pageConfig, ...configs };
748
+ },
749
+ upgradeWidgetConfig() {
750
+ const ids = [];
751
+ const upgradeWidget = (arr, parentId) => {
752
+ arr.forEach((item) => {
753
+ const oldId = item.id;
754
+ if (parentId) {
755
+ while (ids.includes(item.id)) {
756
+ const code = item.contentType.replace(/-/g, "_");
757
+ item.id = code + "_" + util.genId();
758
+ }
759
+ ids.push(item.id);
760
+ item.i = item.id;
761
+ if (!item.css && !isEmpty(item.style)) {
762
+ let cssStr = ":current {";
763
+ for (const key in item.style) {
764
+ const kebabCase = key.replace(/([A-Z])/g, ($1) => {
765
+ return "-" + $1.toLocaleLowerCase();
766
+ });
767
+ cssStr += `\r
768
+ ${kebabCase}: ${item.style[key]};`;
769
+ }
770
+ cssStr += "\r\n}";
771
+ item.css = cssStr;
772
+ delete item.style;
773
+ }
774
+ const oldKey = parentId + "-" + oldId;
775
+ const oldWidgetConifg = this.widgetConfig[oldKey];
776
+ if (oldWidgetConifg) {
777
+ delete this.widgetConfig[oldKey];
778
+ this.widgetConfig[item.id] = { ...this.widgetConfig[item.id], ...oldWidgetConifg };
779
+ } else if (item.id !== oldId && this.widgetConfig[oldId]) {
780
+ this.widgetConfig[item.id] = { ...this.widgetConfig[oldId] };
781
+ }
782
+ }
783
+ const children = getWidgetChildren(item);
784
+ if (children.length > 0) {
785
+ upgradeWidget(children, parentId ? parentId + "-" + oldId : oldId);
786
+ }
787
+ });
788
+ };
789
+ upgradeWidget(this.widgetList);
790
+ },
791
+ upgradePageConfig() {
792
+ const { css, style } = this.pageConfig;
793
+ if (!css && !isEmpty(style)) {
794
+ let cssStr = ":current {";
795
+ for (const key in style) {
796
+ const kebabCase = key.replace(/([A-Z])/g, ($1) => {
797
+ return "-" + $1.toLocaleLowerCase();
798
+ });
799
+ cssStr += `\r
800
+ ${kebabCase}: ${style[key]};`;
801
+ }
802
+ cssStr += "\r\n}";
803
+ delete this.pageConfig.style;
804
+ this.pageConfig = { ...this.pageConfig, css: cssStr };
805
+ }
806
+ },
807
+ moveUpWidget(parentList, indexOfParentList) {
808
+ if (parentList) {
809
+ if (indexOfParentList === 0) {
810
+ this.vueInstance.$message(this.vueInstance.i18nt("designer.hint.moveUpFirstChildHint"));
811
+ return;
812
+ }
813
+ const tempWidget = parentList[indexOfParentList];
814
+ parentList.splice(indexOfParentList, 1);
815
+ parentList.splice(indexOfParentList - 1, 0, tempWidget);
816
+ }
817
+ },
818
+ moveDownWidget(parentList, indexOfParentList) {
819
+ if (parentList) {
820
+ if (indexOfParentList === parentList.length - 1) {
821
+ this.vueInstance.$message(this.vueInstance.i18nt("designer.hint.moveDownLastChildHint"));
822
+ return;
823
+ }
824
+ const tempWidget = parentList[indexOfParentList];
825
+ parentList.splice(indexOfParentList, 1);
826
+ parentList.splice(indexOfParentList + 1, 0, tempWidget);
827
+ }
828
+ },
829
+ copyNewFieldWidget(origin) {
830
+ const newWidget = cloneDeep(origin);
831
+ const tempId = genId();
832
+ newWidget.id = newWidget.type.replace(/-/g, "") + tempId;
833
+ newWidget.options.name = newWidget.id;
834
+ newWidget.options.label = newWidget.options.label || newWidget.type.toLowerCase();
835
+ delete newWidget.displayName;
836
+ return newWidget;
837
+ },
838
+ copyNewContainerWidget(origin) {
839
+ const newCon = genId(origin);
840
+ newCon.id = newCon.type.replace(/-/g, "") + genId();
841
+ newCon.options.name = newCon.id;
842
+ const newTabPane = cloneDeep(this.getContainerByType("tab-pane"));
843
+ newTabPane.id = "tab-pane-" + genId();
844
+ newTabPane.options.name = "tab1";
845
+ newTabPane.options.label = "tab 1";
846
+ newCon.tabs.push(newTabPane);
847
+ delete newCon.displayName;
848
+ return newCon;
849
+ },
850
+ addWidgetByInfo(widgetInfo, parentWidget) {
851
+ const widget = {
852
+ id: widgetInfo.CODE + "_" + genId(),
853
+ contentType: widgetInfo.CODE,
854
+ title: widgetInfo.TITLE
855
+ };
856
+ if (widgetInfo.COMPONENT_SOURCE === "custom") {
857
+ widget.type = "custom";
858
+ }
859
+ if (parentWidget) {
860
+ if (!parentWidget.items) {
861
+ parentWidget.items = [widget];
862
+ } else {
863
+ parentWidget.items.push(widget);
864
+ }
865
+ } else {
866
+ this.widgetList.push(widget);
867
+ }
868
+ if (widgetInfo.CODE === "chart") {
869
+ this.updateWidgetConfig(widget.id, { metaId: this.page.metaId });
870
+ }
871
+ this.setSelected(widget);
872
+ },
873
+ addWidgets(widgets, parentWidget, option = {}) {
874
+ const { defaultSelected = true } = option;
875
+ if (parentWidget) {
876
+ if (!parentWidget.items) {
877
+ parentWidget.items = [...widgets];
878
+ } else {
879
+ parentWidget.items.push(...widgets);
880
+ }
881
+ } else {
882
+ this.widgetList.push(...widgets);
883
+ }
884
+ if (defaultSelected) this.setSelected(widgets[widgets.length - 1]);
885
+ },
886
+ addWidget(widget, parentWidget, option = {}) {
887
+ const { defaultSelected = true } = option;
888
+ if (parentWidget) {
889
+ if (!parentWidget.items) {
890
+ parentWidget.items = [widget];
891
+ } else {
892
+ parentWidget.items.push(widget);
893
+ }
894
+ } else {
895
+ this.widgetList.push(widget);
896
+ }
897
+ if (defaultSelected) this.setSelected(widget);
898
+ },
899
+ // 查找父组件(公共方法):插槽里的组件返回插槽宿主;根级返回 null;不存在返回 undefined
900
+ findParentWidget(targetId) {
901
+ const entry = lookup(targetId);
902
+ return entry ? asReactive(entry.parent) : void 0;
903
+ },
904
+ copyWidget(widget, parentWidget) {
905
+ if (this.findWidgetSlot(widget.id)) {
906
+ this.vueInstance && this.vueInstance.$message && this.vueInstance.$message("插槽内的组件不支持复制");
907
+ return;
908
+ }
909
+ const newWidget = cloneDeep(widget);
910
+ newWidget.id = widget.contentType + "_" + genId();
911
+ const newConfigs = {
912
+ [newWidget.id]: cloneDeep(this.widgetConfig[widget.id])
913
+ };
914
+ const formatWidget = (arr) => {
915
+ for (const item of arr) {
916
+ const newId = item.contentType + "_" + genId();
917
+ newConfigs[newId] = cloneDeep(this.widgetConfig[item.id]);
918
+ item.id = newId;
919
+ formatWidget(getWidgetChildren(item));
920
+ }
921
+ };
922
+ formatWidget(getWidgetChildren(newWidget));
923
+ if (parentWidget) {
924
+ if (!parentWidget.items) {
925
+ parentWidget.items = [newWidget];
926
+ } else {
927
+ parentWidget.items.push(newWidget);
928
+ }
929
+ } else {
930
+ this.widgetList.push(newWidget);
931
+ }
932
+ this.mergeWidgetConfig(newConfigs);
933
+ this.setSelected(newWidget);
934
+ },
935
+ deleteWidget(widget, parentWidget) {
936
+ delete this.widgetConfig[widget.id];
937
+ const slotInfo = this.findWidgetSlot(widget.id);
938
+ if (slotInfo) {
939
+ this.clearWidgetSlot(slotInfo.parent, slotInfo.slotName);
940
+ if (this.selectedId === widget.id) this.clearSelected();
941
+ return 0;
942
+ }
943
+ if (parentWidget && parentWidget.items) {
944
+ const index = parentWidget.items.findIndex((item) => item.id === widget.id);
945
+ if (index !== -1) {
946
+ parentWidget.items.splice(index, 1);
947
+ return index;
948
+ }
949
+ } else {
950
+ const index = this.widgetList.findIndex((item) => item.id === widget.id);
951
+ if (index !== -1) {
952
+ this.widgetList.splice(index, 1);
953
+ return index;
954
+ }
955
+ }
956
+ },
957
+ addContainerByDbClick(container) {
958
+ const newCon = this.copyNewContainerWidget(container);
959
+ this.widgetList.push(newCon);
960
+ this.setSelected(newCon);
961
+ },
962
+ addFieldByDbClick(widget) {
963
+ const newWidget = this.copyNewFieldWidget(widget);
964
+ if (!!this.selectedWidget && this.selectedWidget.type === "tab") {
965
+ let activeTab = this.selectedWidget.tabs[0];
966
+ this.selectedWidget.tabs.forEach((tabPane) => {
967
+ if (tabPane.options.active) {
968
+ activeTab = tabPane;
969
+ }
970
+ });
971
+ !!activeTab && activeTab.widgetList.push(newWidget);
972
+ } else if (!!this.selectedWidget && !!this.selectedWidget.widgetList) {
973
+ this.selectedWidget.widgetList.push(newWidget);
974
+ } else {
975
+ this.widgetList.push(newWidget);
976
+ }
977
+ this.setSelected(newWidget);
978
+ this.emitHistoryChange();
979
+ },
980
+ addTabPaneOfTabs(tabsWidget) {
981
+ const tabPanes = tabsWidget.tabs;
982
+ const newTabPane = cloneDeep(this.getContainerByType("tab-pane"));
983
+ newTabPane.id = "tab-pane-" + genId();
984
+ newTabPane.options.name = newTabPane.id;
985
+ newTabPane.options.label = "tab " + (tabPanes.length + 1);
986
+ tabPanes.push(newTabPane);
987
+ },
988
+ deleteTabPaneOfTabs(tabsWidget, tpIdx) {
989
+ tabsWidget.tabs.splice(tpIdx, 1);
990
+ },
991
+ emitEvent(evtName, evtData) {
992
+ const handlers = designerEvents.get(evtName);
993
+ if (handlers) handlers.slice().forEach((handler) => handler(evtData));
994
+ },
995
+ handleEvent(evtName, callback) {
996
+ const handlers = designerEvents.get(evtName);
997
+ if (handlers) handlers.push(callback);
998
+ else designerEvents.set(evtName, [callback]);
999
+ },
1000
+ offEvent(evtName, callback) {
1001
+ const handlers = designerEvents.get(evtName);
1002
+ if (!handlers) return;
1003
+ if (!callback) {
1004
+ designerEvents.delete(evtName);
1005
+ return;
1006
+ }
1007
+ const index = handlers.indexOf(callback);
1008
+ if (index > -1) handlers.splice(index, 1);
1009
+ },
1010
+ // 快照存三段 JSON 字符串:无响应式、内存紧凑(此前每步 cloneDeep 三份全量数据且全部深度代理);
1011
+ // toRaw 脱掉顶层代理,减少序列化时的 Proxy 开销
1012
+ takeSnapshot() {
1013
+ return {
1014
+ widgetList: JSON.stringify(toRaw(this.widgetList)),
1015
+ widgetConfig: JSON.stringify(toRaw(this.widgetConfig)),
1016
+ pageConfig: JSON.stringify(toRaw(this.pageConfig))
1017
+ };
1018
+ },
1019
+ applySnapshot(snapshot) {
1020
+ this.widgetList = JSON.parse(snapshot.widgetList);
1021
+ this.widgetConfig = JSON.parse(snapshot.widgetConfig);
1022
+ this.pageConfig = JSON.parse(snapshot.pageConfig);
1023
+ },
1024
+ // 加载页面后重置为单步历史,首次操作即可撤销回初始状态
1025
+ initHistoryData() {
1026
+ this.historyData.index = 0;
1027
+ this.historyData.steps = [this.takeSnapshot()];
1028
+ },
1029
+ emitHistoryChange() {
1030
+ if (this.historyData.index === this.historyData.maxStep - 1) {
1031
+ this.historyData.steps.shift();
1032
+ } else {
1033
+ this.historyData.index++;
1034
+ }
1035
+ this.historyData.steps[this.historyData.index] = this.takeSnapshot();
1036
+ this.savePageContentToStorage();
1037
+ if (this.historyData.index < this.historyData.steps.length - 1) {
1038
+ this.historyData.steps = this.historyData.steps.slice(0, this.historyData.index + 1);
1039
+ }
1040
+ },
1041
+ saveCurrentHistoryStep() {
1042
+ this.historyData.steps[this.historyData.index] = this.takeSnapshot();
1043
+ this.savePageContentToStorage();
1044
+ },
1045
+ undoHistoryStep() {
1046
+ if (this.historyData.index !== 0) {
1047
+ this.historyData.index--;
1048
+ }
1049
+ this.applySnapshot(this.historyData.steps[this.historyData.index]);
1050
+ },
1051
+ redoHistoryStep() {
1052
+ if (this.historyData.index !== this.historyData.steps.length - 1) {
1053
+ this.historyData.index++;
1054
+ }
1055
+ this.applySnapshot(this.historyData.steps[this.historyData.index]);
1056
+ },
1057
+ undoEnabled() {
1058
+ return this.historyData.index > 0 && this.historyData.steps.length > 0;
1059
+ },
1060
+ redoEnabled() {
1061
+ return this.historyData.index < this.historyData.steps.length - 1;
1062
+ },
1063
+ // 300ms 防抖:连续操作只写一次 localStorage;直接复用快照字符串,不再重复 stringify
1064
+ savePageContentToStorage() {
1065
+ if (saveTimer) clearTimeout(saveTimer);
1066
+ saveTimer = setTimeout(() => {
1067
+ saveTimer = null;
1068
+ const snapshot = this.historyData.steps[this.historyData.index] || this.takeSnapshot();
1069
+ storage.set("widget__list__backup", snapshot.widgetList);
1070
+ storage.set("widget__config__backup", snapshot.widgetConfig);
1071
+ storage.set("page__config__backup", snapshot.pageConfig);
1072
+ }, 300);
1073
+ },
1074
+ loadPageContentFromStorage() {
1075
+ const widgetListBackup = storage.get("widget__list__backup");
1076
+ if (widgetListBackup) {
1077
+ this.widgetList = JSON.parse(widgetListBackup);
1078
+ }
1079
+ const widgetConfigBackup = storage.get("widget__config__backup");
1080
+ if (widgetConfigBackup) {
1081
+ Object.assign(this.widgetConfig, JSON.parse(widgetConfigBackup));
1082
+ }
1083
+ const pageConfigBackup = storage.get("page__config__backup");
1084
+ if (pageConfigBackup) {
1085
+ Object.assign(this.pageConfig, JSON.parse(pageConfigBackup));
1086
+ }
1087
+ },
1088
+ isExistId(id) {
1089
+ return lookup(id) !== void 0;
1090
+ },
1091
+ // 停掉索引 watch 与待写入的 storage 定时器;PageDesigner.beforeUnmount 调用
1092
+ dispose() {
1093
+ scope.stop();
1094
+ if (saveTimer) {
1095
+ clearTimeout(saveTimer);
1096
+ saveTimer = null;
1097
+ }
1098
+ },
1099
+ genId(widgetCode) {
1100
+ const code = widgetCode.replace(/-/g, "_");
1101
+ let id = code + "_" + util.genId();
1102
+ while (this.isExistId(id)) {
1103
+ id = code + "_" + util.genId();
1104
+ }
1105
+ return id;
1106
+ }
1107
+ });
1108
+ scope.run(() => {
1109
+ watch(() => state.widgetList, () => {
1110
+ indexDirty = true;
1111
+ }, { deep: true, flush: "sync" });
1112
+ });
1113
+ return state;
1114
+ }
1115
+ export {
1116
+ createDesigner,
1117
+ getWidgetChildren,
1118
+ getWidgetSlots
1119
+ };