@epxing/designer 5.3.0-beta.2 → 5.3.0-beta.3

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 (33) hide show
  1. package/API.md +1 -1
  2. package/README.md +46 -46
  3. package/dist/src/page-designer/PageDesigner.js +11 -0
  4. package/dist/src/page-designer/designer.js +21 -0
  5. package/dist/src/page-designer/previews/add-form/Preview.js +1 -1
  6. package/dist/src/page-designer/previews/add-form/Preview.vue.js +19 -8
  7. package/dist/src/page-designer/setting-panel/Setting.js +46 -10
  8. package/dist/src/visual/config-page/ComponentLibraryDialog.js +8 -2
  9. package/dist/src/visual/config-page/DashboardMobile.js +1 -1
  10. package/dist/style.css +116 -112
  11. package/package.json +8 -8
  12. package/src/index.js +27 -27
  13. package/src/page-designer/PageDesigner.vue +11 -0
  14. package/src/page-designer/designer.js +1322 -1299
  15. package/src/page-designer/previews/add-form/Preview.vue +43 -44
  16. package/src/page-designer/setting-panel/Setting.vue +24 -2
  17. package/src/page-designer/widget-preview/Mixin.js +285 -285
  18. package/src/page-designer/widget-preview/Preview.vue +322 -322
  19. package/src/page-designer/widget-preview/WidgetWrapper.vue +197 -197
  20. package/src/page-designer/widget-preview/directive.js +258 -258
  21. package/src/visual/CategoryList.vue +563 -563
  22. package/src/visual/ComponentList.vue +280 -280
  23. package/src/visual/CreatePage.vue +389 -389
  24. package/src/visual/EntityCardList.vue +449 -449
  25. package/src/visual/EntityList.vue +838 -838
  26. package/src/visual/config-page/ComponentLibraryDialog.vue +7 -1
  27. package/src/visual/config-page/DashboardMobile.vue +934 -934
  28. package/src/visual/widgets/ProcessFormItemVisual.vue +58 -58
  29. package/types/index.d.ts +22 -22
  30. package/types/page-designer.d.ts +3 -3
  31. package/types/visual-component.d.ts +1 -1
  32. package/types/visual-entity-list.d.ts +1 -1
  33. package/types/visual-entity-sub-list.d.ts +1 -1
package/API.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  页面设计器、可视化配置组件、字段配置面板及预览组件集合。
4
4
 
5
- 本页对应包版本 `5.3.0-beta.2`。导出名、子路径和签名从当前源码、package.json 与类型声明生成。
5
+ 本页对应包版本 `5.3.0-beta.3`。导出名、子路径和签名从当前源码、package.json 与类型声明生成。
6
6
 
7
7
  ## 安装与使用
8
8
 
package/README.md CHANGED
@@ -1,46 +1,46 @@
1
- # @epxing/designer
2
-
3
- [完整公开 API、导入方式与示例](./API.md)
4
-
5
- 从 5.3.0-beta.2 起,导入本包 JS 时自动加载包级样式,根入口和稳定子路径均无需手动引入 style.css。显式样式入口继续兼容旧代码;产品覆盖样式放在框架导入之后。
6
-
7
- 可视化配置体系包 - **设计态独有,运行时按需加载**。
8
-
9
- ## 范围
10
-
11
- - `src/frame/page-designer/`(整目录)
12
- - 各 package 的 `Visual.vue` / `Config.vue`(T07 抽出,14+ 处)
13
- - 各 package 的 `Preview.vue`(T08 抽出,35+ 处)
14
- - `src/frame/views/visual/`
15
- - `src/frame/views/{FormDesign,ExcelDesign,Bpmn}.vue`
16
- - `src/frame/views/report/` / `src/frame/views/match/`
17
- - `src/frame/packages/visual-config-page/`
18
-
19
- ## 加载策略
20
-
21
- `apps/platform` 路由层 `() => import('@epxing/designer')` 懒加载,运行时进入设计页面才下载。
22
-
23
- ## 依赖
24
-
25
- - `@epxing/utils`
26
- - `@epxing/theme`
27
- - `@epxing/core`
28
- - `@epxing/components`
29
-
30
- ## 状态
31
-
32
- 已提供公共根入口、稳定组件子路径和类型声明。
33
-
34
-
35
- ## 独立包公共入口(2026-10-22)
36
-
37
- 根入口及稳定子路径提供类型声明。先安装 core 与需要的 component,再按需安装本包。
38
-
39
- 产品设计面板可从根入口具名导入 VisualComponent、VisualEntityList 等,或默认导入 `@epxing/designer/visual-component`。远程产品通过 epxShared 复用宿主设计态组件,整包安装由宿主负责。详见 `docs/guide/getting-started/packages.md`。
40
-
41
- ```js
42
- import plugin from '@epxing/designer'
43
- app.use(plugin)
44
- ```
45
-
46
- 工作区构建:`pnpm --filter @epxing/designer build`。pack/publish 的 prepack 会重建;版本由 Changesets 独立管理。旧 `/src/*` 入口保留。完整初始化、打包与远程共享流程见 docs/build-and-publish.md。
1
+ # @epxing/designer
2
+
3
+ [完整公开 API、导入方式与示例](./API.md)
4
+
5
+ 从 5.3.0-beta.2 起,导入本包 JS 时自动加载包级样式,根入口和稳定子路径均无需手动引入 style.css。显式样式入口继续兼容旧代码;产品覆盖样式放在框架导入之后。
6
+
7
+ 可视化配置体系包 - **设计态独有,运行时按需加载**。
8
+
9
+ ## 范围
10
+
11
+ - `src/frame/page-designer/`(整目录)
12
+ - 各 package 的 `Visual.vue` / `Config.vue`(T07 抽出,14+ 处)
13
+ - 各 package 的 `Preview.vue`(T08 抽出,35+ 处)
14
+ - `src/frame/views/visual/`
15
+ - `src/frame/views/{FormDesign,ExcelDesign,Bpmn}.vue`
16
+ - `src/frame/views/report/` / `src/frame/views/match/`
17
+ - `src/frame/packages/visual-config-page/`
18
+
19
+ ## 加载策略
20
+
21
+ `apps/platform` 路由层 `() => import('@epxing/designer')` 懒加载,运行时进入设计页面才下载。
22
+
23
+ ## 依赖
24
+
25
+ - `@epxing/utils`
26
+ - `@epxing/theme`
27
+ - `@epxing/core`
28
+ - `@epxing/components`
29
+
30
+ ## 状态
31
+
32
+ 已提供公共根入口、稳定组件子路径和类型声明。
33
+
34
+
35
+ ## 独立包公共入口(2026-10-22)
36
+
37
+ 根入口及稳定子路径提供类型声明。先安装 core 与需要的 component,再按需安装本包。
38
+
39
+ 产品设计面板可从根入口具名导入 VisualComponent、VisualEntityList 等,或默认导入 `@epxing/designer/visual-component`。远程产品通过 epxShared 复用宿主设计态组件,整包安装由宿主负责。详见 `docs/guide/getting-started/packages.md`。
40
+
41
+ ```js
42
+ import plugin from '@epxing/designer'
43
+ app.use(plugin)
44
+ ```
45
+
46
+ 工作区构建:`pnpm --filter @epxing/designer build`。pack/publish 的 prepack 会重建;版本由 Changesets 独立管理。旧 `/src/*` 入口保留。完整初始化、打包与远程共享流程见 docs/build-and-publish.md。
@@ -151,6 +151,17 @@ const _sfc_main = {
151
151
  };
152
152
  }
153
153
  });
154
+ },
155
+ // 切换组件后预览区会按新组件重建 DOM,选中浮层需重新定位到新元素(选中其它组件由上面的监听处理)
156
+ "designer.selectedWidget.contentType"() {
157
+ const widget = this.designer.selectedWidget;
158
+ if (!widget || this.selectedWidgetData.widget !== widget) return;
159
+ this.$nextTick(() => {
160
+ this.selectedWidgetData = {
161
+ ...this.selectedWidgetData,
162
+ element: document.querySelector(`[data-widget-id="${widget.id}"]`)
163
+ };
164
+ });
154
165
  }
155
166
  },
156
167
  methods: {
@@ -955,6 +955,27 @@ function createDesigner(vueInstance) {
955
955
  }
956
956
  }
957
957
  },
958
+ /**
959
+ * 切换组件类型:只换 contentType(及自定义组件的 type 标记),组件 id 不变,
960
+ * 因此按 id 存的组件配置(itemConfigs)、子组件、样式等全部保留
961
+ * @param { Object } widget 要切换的组件
962
+ * @param { Object } widgetInfo 目标组件记录(组件库中的 FM_PAGE)
963
+ */
964
+ switchWidget(widget, widgetInfo) {
965
+ const oldInfo = this.getWidgetByType(widget.contentType, widget.type) || {};
966
+ const property = {
967
+ contentType: widgetInfo.CODE,
968
+ type: widgetInfo.COMPONENT_SOURCE === "custom" ? "custom" : null
969
+ };
970
+ if (!widget.title || widget.title === oldInfo.TITLE) {
971
+ property.title = widgetInfo.TITLE;
972
+ }
973
+ this.updateWidget(widget.id, property);
974
+ const { metaId } = this.widgetConfig[widget.id] || {};
975
+ if (widgetInfo.CODE === "chart" && !metaId) {
976
+ this.updateWidgetConfig(widget.id, { metaId: this.page.metaId });
977
+ }
978
+ },
958
979
  addContainerByDbClick(container) {
959
980
  const newCon = this.copyNewContainerWidget(container);
960
981
  this.widgetList.push(newCon);
@@ -2,7 +2,7 @@ import '../../../../style.css';
2
2
  import _sfc_main from "./Preview.vue.js";
3
3
  /* empty css */
4
4
  import _export_sfc from "../../../../_virtual/_plugin-vue_export-helper.js";
5
- const AddFormPreview = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-59a0f3d2"]]);
5
+ const AddFormPreview = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-0554afd8"]]);
6
6
  export {
7
7
  AddFormPreview as default
8
8
  };
@@ -1,4 +1,4 @@
1
- import { createVNode, createTextVNode, resolveComponent, mergeProps, isVNode } from "vue";
1
+ import { createVNode, resolveComponent, mergeProps, createTextVNode, isVNode } from "vue";
2
2
  import previewMixin from "../../widget-preview/Mixin.js";
3
3
  import { MobileActionSheet } from "@epxing/components/src/mobile";
4
4
  function _isSlot(s) {
@@ -196,14 +196,13 @@ const _sfc_main = {
196
196
  }, [this.renderCatalogList(this.childWidgetList)])]);
197
197
  },
198
198
  renderForm() {
199
- let _slot2;
200
199
  const {
201
- operateFlag,
202
- showCatalog
200
+ operatePosition
203
201
  } = this.$configs;
202
+ const operateTop = operatePosition === "top" && !this.$isMobile;
204
203
  return createVNode("div", {
205
204
  "class": "epx-add-form__content"
206
- }, [createVNode("div", {
205
+ }, [operateTop && this.renderOperateArea(true), createVNode("div", {
207
206
  "class": "epx-add-form__field-group epx-page-designer-widget-preview__drop-zone",
208
207
  "ref": "addForm"
209
208
  }, [createVNode("div", {
@@ -223,7 +222,17 @@ const _sfc_main = {
223
222
  }, [this.renderComponent(component)]);
224
223
  }), this.childWidgetList.length === 0 && createVNode("div", {
225
224
  "class": "epx-page-designer-widget-preview__no-widget"
226
- }, [createTextVNode("拖拽表单项到这里")])])]), !this.readonly && operateFlag && !(showCatalog && !this.$isMobile) && createVNode("div", null, [this.$isMobile ? createVNode("div", {
225
+ }, [createTextVNode("拖拽表单项到这里")])])]), !operateTop && this.renderOperateArea(false)]);
226
+ },
227
+ // 表单区按钮区;PC 端开了目录时按钮在目录区渲染,此处不渲染
228
+ renderOperateArea(top) {
229
+ let _slot2;
230
+ const {
231
+ operateFlag,
232
+ showCatalog
233
+ } = this.$configs;
234
+ if (this.readonly || !operateFlag || showCatalog && !this.$isMobile) return null;
235
+ return createVNode("div", null, [this.$isMobile ? createVNode("div", {
227
236
  "class": ["epx-add-form__m-buttongroup", {
228
237
  "epx-add-form__m-button-more": this.operates.length > 3
229
238
  }]
@@ -257,7 +266,9 @@ const _sfc_main = {
257
266
  }, {
258
267
  default: () => [operate.text]
259
268
  }))])]) : createVNode("div", {
260
- "class": "epx-add-form__button-group"
269
+ "class": ["epx-add-form__button-group", {
270
+ "epx-add-form__button-group--top": top
271
+ }]
261
272
  }, [this.operates.map((operate) => createVNode(resolveComponent("el-button"), mergeProps({
262
273
  "loading": this.httpLoading[operate.handler + "-" + operate.text],
263
274
  "size": "default",
@@ -273,7 +284,7 @@ const _sfc_main = {
273
284
  default: () => [operate.icon && createVNode("i", {
274
285
  "class": [operate.icon]
275
286
  }, null), operate.text]
276
- }))])])]);
287
+ }))])]);
277
288
  }
278
289
  },
279
290
  created() {
@@ -19,7 +19,9 @@ const _sfc_main = {
19
19
  data() {
20
20
  return {
21
21
  activeTab: "property",
22
- showCodeEditor: false
22
+ showCodeEditor: false,
23
+ showPropertyPanel: true,
24
+ showSwitchDialog: false
23
25
  };
24
26
  },
25
27
  computed: {
@@ -33,6 +35,11 @@ const _sfc_main = {
33
35
  if (!this.designer.selectedWidget) return this.designer.page.pageId;
34
36
  return this.designer.selectedWidget.id;
35
37
  },
38
+ // 切换组件后 id 不变,属性面板需按组件类型重建,才能加载新组件的配置面板
39
+ propertyKey() {
40
+ var _a;
41
+ return this.widgetId + "_" + (((_a = this.designer.selectedWidget) == null ? void 0 : _a.contentType) || "");
42
+ },
36
43
  widgetConfig() {
37
44
  const { configs = {}, id } = this.designer.selectedWidget;
38
45
  const widgetConfig = this.designer.widgetConfig[id] || {};
@@ -86,6 +93,13 @@ const _sfc_main = {
86
93
  }
87
94
  });
88
95
  },
96
+ // 换成弹窗中选择的组件,组件 id 不变,原配置保留
97
+ switchComponent(widgetInfo) {
98
+ this.showSwitchDialog = false;
99
+ const widget = this.designer.selectedWidget;
100
+ if (!widget || widget.contentType === widgetInfo.CODE) return;
101
+ this.designer.switchWidget(widget, widgetInfo);
102
+ },
89
103
  updateWidgetConfig(v) {
90
104
  this.designer.updateWidgetConfig(this.designer.selectedWidget.id, v);
91
105
  },
@@ -175,6 +189,8 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
175
189
  const _component_epx_page_designer_setting_style = resolveComponent("epx-page-designer-setting-style");
176
190
  const _component_epx_page_designer_setting_advance = resolveComponent("epx-page-designer-setting-advance");
177
191
  const _component_el_tabs = resolveComponent("el-tabs");
192
+ const _component_epx_visual_component_library_dialog = resolveComponent("epx-visual-component-library-dialog");
193
+ const _component_el_dialog = resolveComponent("el-dialog");
178
194
  const _component_el_container = resolveComponent("el-container");
179
195
  return $props.designer.selectedWidget || $props.designer.mode !== "template" && $props.designer.mode !== "component" ? (openBlock(), createBlock(_component_el_container, {
180
196
  key: 0,
@@ -184,7 +200,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
184
200
  createVNode(_component_el_tabs, {
185
201
  class: "epx-page-designer-setting__tabs",
186
202
  modelValue: $data.activeTab,
187
- "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => $data.activeTab = $event),
203
+ "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => $data.activeTab = $event),
188
204
  stretch: true
189
205
  }, {
190
206
  default: withCtx(() => [
@@ -194,7 +210,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
194
210
  }, {
195
211
  default: withCtx(() => [
196
212
  !$props.designer.selectedWidget ? (openBlock(), createElementBlock("div", _hoisted_1, [
197
- _cache[6] || (_cache[6] = createElementVNode("label", { class: "epx-page-designer-setting__widget-title-label" }, "页面", -1)),
213
+ _cache[8] || (_cache[8] = createElementVNode("label", { class: "epx-page-designer-setting__widget-title-label" }, "页面", -1)),
198
214
  createTextVNode(toDisplayString($props.designer.page.title) + " ", 1),
199
215
  createElementVNode("i", {
200
216
  class: "el-icon-copy-document",
@@ -202,7 +218,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
202
218
  onClick: _cache[0] || (_cache[0] = (...args) => $options.copyPageId && $options.copyPageId(...args))
203
219
  })
204
220
  ])) : (openBlock(), createElementBlock("div", _hoisted_2, [
205
- _cache[9] || (_cache[9] = createElementVNode("label", { class: "epx-page-designer-setting__widget-title-label" }, "组件类型", -1)),
221
+ _cache[11] || (_cache[11] = createElementVNode("label", { class: "epx-page-designer-setting__widget-title-label" }, "组件类型", -1)),
206
222
  createTextVNode(toDisplayString($options.widgetInfo.TITLE || $options.widgetInfo.NAME) + " ", 1),
207
223
  $options.widgetInfo.HELP ? (openBlock(), createElementBlock("i", {
208
224
  key: 0,
@@ -214,20 +230,25 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
214
230
  key: 1,
215
231
  class: "epx-page-designer-setting__widget-split",
216
232
  onClick: _cache[2] || (_cache[2] = (...args) => $options.splitTemplate && $options.splitTemplate(...args))
217
- }, [..._cache[7] || (_cache[7] = [
233
+ }, [..._cache[9] || (_cache[9] = [
218
234
  createElementVNode("i", {
219
235
  class: "epx-icon-quxiaofenzu",
220
236
  title: "拆分模板"
221
237
  }, null, -1),
222
238
  createElementVNode("span", null, "拆分", -1)
223
- ])])) : createCommentVNode("", true),
239
+ ])])) : (openBlock(), createElementBlock("i", {
240
+ key: 2,
241
+ class: "epx-page-designer-setting__widget-switch el-icon-sort",
242
+ title: "切换组件",
243
+ onClick: _cache[3] || (_cache[3] = ($event) => $data.showSwitchDialog = true)
244
+ })),
224
245
  createVNode(_component_el_popover, {
225
246
  ref: "codeEditorPopover",
226
247
  placement: "bottom",
227
248
  width: "400",
228
249
  trigger: "click",
229
- onBeforeEnter: _cache[3] || (_cache[3] = ($event) => $data.showCodeEditor = true),
230
- onAfterLeave: _cache[4] || (_cache[4] = ($event) => $data.showCodeEditor = false)
250
+ onBeforeEnter: _cache[4] || (_cache[4] = ($event) => $data.showCodeEditor = true),
251
+ onAfterLeave: _cache[5] || (_cache[5] = ($event) => $data.showCodeEditor = false)
231
252
  }, {
232
253
  reference: withCtx(() => [
233
254
  createVNode(_component_el_button, {
@@ -235,7 +256,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
235
256
  round: "",
236
257
  size: "small"
237
258
  }, {
238
- default: withCtx(() => [..._cache[8] || (_cache[8] = [
259
+ default: withCtx(() => [..._cache[10] || (_cache[10] = [
239
260
  createElementVNode("i", { class: "epx-icon-code" }, null, -1)
240
261
  ])]),
241
262
  _: 1
@@ -252,7 +273,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
252
273
  }, 512)
253
274
  ])),
254
275
  (openBlock(), createBlock(_component_epx_page_designer_setting_property, {
255
- key: $options.widgetId,
276
+ key: $options.propertyKey,
256
277
  designer: $props.designer,
257
278
  relationList: $props.relationList
258
279
  }, null, 8, ["designer", "relationList"]))
@@ -285,6 +306,21 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
285
306
  })) : createCommentVNode("", true)
286
307
  ]),
287
308
  _: 1
309
+ }, 8, ["modelValue"]),
310
+ createVNode(_component_el_dialog, {
311
+ title: "切换组件",
312
+ modelValue: $data.showSwitchDialog,
313
+ "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => $data.showSwitchDialog = $event),
314
+ width: "960px",
315
+ "append-to-body": ""
316
+ }, {
317
+ default: withCtx(() => [
318
+ createVNode(_component_epx_visual_component_library_dialog, {
319
+ "hide-template": "",
320
+ onClick: $options.switchComponent
321
+ }, null, 8, ["onClick"])
322
+ ]),
323
+ _: 1
288
324
  }, 8, ["modelValue"])
289
325
  ]),
290
326
  _: 1
@@ -6,7 +6,12 @@ import _export_sfc from "../../../_virtual/_plugin-vue_export-helper.js";
6
6
  const _sfc_main = {
7
7
  name: "epx-visual-component-library-dialog",
8
8
  props: {
9
- initialTerminal: { type: String, default: "pc" }
9
+ initialTerminal: { type: String, default: "pc" },
10
+ // 隐藏「模板组件」分类(如切换组件时,模板不能作为切换目标)
11
+ hideTemplate: {
12
+ type: Boolean,
13
+ default: false
14
+ }
10
15
  },
11
16
  data() {
12
17
  return {
@@ -25,6 +30,7 @@ const _sfc_main = {
25
30
  ]),
26
31
  componentTypeList() {
27
32
  const code = this.getCodeById("COMPONENT_TYPE") || [];
33
+ if (this.hideTemplate) return code;
28
34
  return [...code, { code: "template", name: "模板组件" }];
29
35
  }
30
36
  },
@@ -244,7 +250,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
244
250
  ])
245
251
  ]);
246
252
  }
247
- const ComponentLibraryDialog = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-de84464b"]]);
253
+ const ComponentLibraryDialog = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-be6fc4ff"]]);
248
254
  export {
249
255
  ComponentLibraryDialog as default
250
256
  };
@@ -1109,7 +1109,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
1109
1109
  }, 8, ["modelValue"])
1110
1110
  ], 2);
1111
1111
  }
1112
- const DashboardMobile = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-ab9c83f8"]]);
1112
+ const DashboardMobile = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-49553b15"]]);
1113
1113
  export {
1114
1114
  DashboardMobile as default
1115
1115
  };