cloud-web-corejs 1.1.0-dev.54 → 1.1.0-dev.55

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cloud-web-corejs",
3
3
  "private": false,
4
- "version": "1.1.0-dev.54",
4
+ "version": "1.1.0-dev.55",
5
5
  "scripts": {
6
6
  "build:ace-resources": "node build/build-ace-resources.js",
7
7
  "build:tinymce-resources": "node build/build-tinymce-resources.js",
@@ -57,6 +57,7 @@ let chartContainers = [],
57
57
  },
58
58
  scriptList: [],
59
59
  formType: 0,
60
+ dialogScope: null,
60
61
  getConfig: {
61
62
  accessType: "1",
62
63
  accessUrl: null,
@@ -1,8 +1,14 @@
1
1
  <template>
2
2
  <el-dialog
3
+ ref="pageDialog"
3
4
  :visible.sync="showDialog"
4
5
  v-el-drag-dialog
5
- v-el-dialog-center
6
+ v-el-dialog-center="!isPageScope"
7
+ :class="{
8
+ 'xform-page-dialog-wrapper': isPageScope,
9
+ 'xform-page-form-dialog-wrapper': isPageScope,
10
+ 'xform-page-dialog-wrapper--top': pageDialogHasTop,
11
+ }"
6
12
  v-bind="dialogConfig"
7
13
  @close="close"
8
14
  >
@@ -13,7 +19,11 @@
13
19
  v-bind="bodyConfig"
14
20
  v-if="listHost"
15
21
  >
16
- <list-view-host :formCode="listFormCode" :param="dialogParam" />
22
+ <list-view-host
23
+ :formCode="listFormCode"
24
+ :param="dialogParam"
25
+ :dialogScope="option.dialogScope"
26
+ />
17
27
  </div>
18
28
  <div class="cont designer-view" v-bind="bodyConfig" id="containt" v-else>
19
29
  <v-form-render
@@ -30,6 +40,7 @@
30
40
  @reload="reload"
31
41
  v-bind="formConfig"
32
42
  :param="dialogParam"
43
+ :dialogScope="option.dialogScope"
33
44
  :dataTableOption="dialogDataTableOption"
34
45
  class="data-table_height"
35
46
  @hook:mounted="handleFormMounted"
@@ -75,6 +86,10 @@
75
86
 
76
87
  <script>
77
88
  import VFormRender from "../../../../../components/xform/form-render/index.vue";
89
+ import {
90
+ pageScopedDialogMixin,
91
+ pageDialogTop,
92
+ } from "@base/components/xform/form-render/pageDialogScope";
78
93
  import {
79
94
  resolveActionButtons,
80
95
  hasButtonPermission,
@@ -95,7 +110,7 @@ export default {
95
110
  visiable: Boolean,
96
111
  option: Object,
97
112
  },
98
- mixins: [],
113
+ mixins: [pageScopedDialogMixin],
99
114
  inject: ["getFormConfig"],
100
115
 
101
116
  mounted() {},
@@ -171,6 +186,15 @@ export default {
171
186
  config = Object.assign({}, config, this.option.dialogConfig, {
172
187
  customClass,
173
188
  });
189
+ if (this.isPageScope) {
190
+ Object.assign(config, {
191
+ appendToBody: false,
192
+ modalAppendToBody: false,
193
+ modal: false,
194
+ lockScroll: false,
195
+ top: pageDialogTop(this.option.dialogConfig?.top),
196
+ });
197
+ }
174
198
  config.title = this.$t1(config.title);
175
199
  return config;
176
200
  },
@@ -236,7 +260,9 @@ export default {
236
260
  method: `post`,
237
261
  data: data,
238
262
  isLoading: true,
239
- loadingTarget: document.body,
263
+ loadingTarget: this.isPageScope
264
+ ? this.option.pageDialogHost
265
+ : document.body,
240
266
  modalStrictly: true,
241
267
  success: (res) => {
242
268
  let formTemplate = res.objx || {};
@@ -1,8 +1,13 @@
1
1
  <template>
2
2
  <el-dialog
3
+ ref="pageDialog"
3
4
  :visible.sync="showDialog"
4
5
  v-el-drag-dialog
5
- v-el-dialog-center
6
+ v-el-dialog-center="!isPageScope"
7
+ :class="{
8
+ 'xform-page-dialog-wrapper': isPageScope,
9
+ 'xform-page-dialog-wrapper--top': pageDialogHasTop,
10
+ }"
6
11
  v-bind="dialogConfig"
7
12
  @close="close"
8
13
  >
@@ -22,6 +27,7 @@
22
27
  :dataTableOption="dataTableOption"
23
28
  v-bind="formConfig"
24
29
  :param="dialogParam"
30
+ :dialogScope="option.dialogScope"
25
31
  class="data-table_height labMargin"
26
32
  />
27
33
  </div>
@@ -72,12 +78,16 @@
72
78
  <script>
73
79
  import { selectDialogMixins } from "../../../../../mixins/selectDialog/index.js";
74
80
  import VFormRender from "../../../../../components/xform/form-render/index.vue";
81
+ import {
82
+ pageScopedDialogMixin,
83
+ pageDialogTop,
84
+ } from "@base/components/xform/form-render/pageDialogScope";
75
85
  import { traverseAllWidgetsNew } from "../../../../../components/xform/utils/util";
76
86
 
77
87
  export default {
78
88
  components: { VFormRender },
79
89
  props: ["visiable", "multi", "rows", "param", "widget", "option"],
80
- mixins: [selectDialogMixins],
90
+ mixins: [selectDialogMixins, pageScopedDialogMixin],
81
91
  inject: ["getFormConfig"],
82
92
  mounted() {},
83
93
  data() {
@@ -172,6 +182,15 @@ export default {
172
182
  config = Object.assign({}, config, this.option.dialogConfig, {
173
183
  customClass,
174
184
  });
185
+ if (this.isPageScope) {
186
+ Object.assign(config, {
187
+ appendToBody: false,
188
+ modalAppendToBody: false,
189
+ modal: false,
190
+ lockScroll: false,
191
+ top: pageDialogTop(this.option.dialogConfig?.top),
192
+ });
193
+ }
175
194
  config.title = this.$t1(config.title);
176
195
  return config;
177
196
  },
@@ -228,7 +247,9 @@ export default {
228
247
  method: `post`,
229
248
  data: data,
230
249
  isLoading: true,
231
- loadingTarget: document.body,
250
+ loadingTarget: this.isPageScope
251
+ ? this.option.pageDialogHost
252
+ : document.body,
232
253
  modalStrictly: true,
233
254
  success: (res) => {
234
255
  let formTemplate = res.objx || {};
@@ -300,7 +321,9 @@ export default {
300
321
  tableAlias: this.formCode,
301
322
  },
302
323
  isLoading: true,
303
- loadingTarget: document.body,
324
+ loadingTarget: this.isPageScope
325
+ ? this.option.pageDialogHost
326
+ : document.body,
304
327
  modalStrictly: true,
305
328
  success: (res) => {
306
329
  let formData = res.objx && res.objx.data ? res.objx.data : {};
@@ -11,16 +11,23 @@
11
11
  :clearable="field.options.clearable"
12
12
  :minlength="field.options.minLength" :maxlength="field.options.maxLength"
13
13
  :show-word-limit="field.options.showWordLimit"
14
- :prefix-icon="field.options.prefixIcon" :suffix-icon="field.options.suffixIcon"
14
+ :prefix-icon="field.options.prefixIcon" :suffix-icon="clickableSuffix ? '' : field.options.suffixIcon"
15
15
  @focus="handleFocusCustomEvent" @blur="handleBlurCustomEvent" @input="handleInputCustomEvent"
16
16
  @change="handleChangeEvent"
17
17
  :style="'width:'+field.options.widgetWidth+' !important;'"
18
18
  :class="{'custom-width':field.options.widgetWidth!=null}">
19
19
  <el-button slot="append" v-if="field.options.appendButton" :disabled="field.options.disabled || field.options.appendButtonDisabled"
20
20
  :class="field.options.buttonIcon" @click.native="emitAppendButtonClick"></el-button>
21
+ <i v-if="clickableSuffix" slot="suffix"
22
+ :class="field.options.suffixIcon"
23
+ class="el-input__icon suffix-icon-clickable"
24
+ @click.stop="handleSuffixIconClick"></i>
21
25
  </el-input>
22
26
  <template v-if="isReadMode">
23
27
  <span class="readonly-mode-field pre-wrap" :title="contentForReadMode">{{contentForReadMode}}</span>
28
+ <i v-if="readModeSuffix" :class="field.options.suffixIcon"
29
+ class="el-input__icon suffix-icon-clickable"
30
+ @click.stop="handleSuffixIconClick"></i>
24
31
  </template>
25
32
  </form-item-wrapper>
26
33
  </template>
@@ -82,6 +89,18 @@
82
89
  contentForReadMode() {
83
90
  return this.fieldModel ? this.fieldModel : ''
84
91
  },
92
+ clickableSuffix() {
93
+ //尾部图标可点击(编辑态):开关开启且已配置suffixIcon;开启后suffix-icon改由slot渲染,避免图标重复
94
+ return !!this.field.options.suffixIconClickable
95
+ && !!this.field.options.suffixIcon
96
+ && !this.isReadMode
97
+ },
98
+ readModeSuffix() {
99
+ //只读模式:el-input不渲染,图标单独补充在只读文本旁
100
+ return !!this.field.options.suffixIconClickable
101
+ && !!this.field.options.suffixIcon
102
+ && this.isReadMode
103
+ },
85
104
 
86
105
  },
87
106
  beforeCreate() {
@@ -108,7 +127,11 @@
108
127
  },
109
128
 
110
129
  methods: {
111
-
130
+ handleSuffixIconClick() {
131
+ if (this.designState) return
132
+ //复用后置按钮的点击链:onAppendButtonClick脚本 → dispatch('appendButtonClick') → handleCustomClickEvent
133
+ this.emitAppendButtonClick()
134
+ }
112
135
  }
113
136
  }
114
137
  </script>
@@ -116,4 +139,7 @@
116
139
  <style lang="scss" scoped>
117
140
  @import "~@base/styles/theme-variables.scss"; //* form-item-wrapper已引入,还需要重复引入吗? *//
118
141
 
142
+ .suffix-icon-clickable {
143
+ cursor: pointer;
144
+ }
119
145
  </style>
@@ -9,11 +9,24 @@
9
9
  @submit.native.prevent
10
10
  >
11
11
  <el-collapse v-model="formActiveCollapseNames" class="setting-collapse">
12
- <el-collapse-item
13
- name="1"
14
- :title="i18nt('designer.setting.basicSetting')"
15
- >
16
- <el-form-item class="form-item-label-top" :label="i18nt('数据库表')">
12
+ <el-collapse-item
13
+ name="1"
14
+ :title="i18nt('designer.setting.basicSetting')"
15
+ >
16
+ <el-form-item
17
+ v-if="formConfig.layoutType === 'PC'"
18
+ class="form-item-label-top"
19
+ label="业务弹框作用域"
20
+ >
21
+ <el-radio-group v-model="dialogScopeValue">
22
+ <el-radio label="global">全局</el-radio>
23
+ <el-radio label="page">当前页面</el-radio>
24
+ </el-radio-group>
25
+ <div style="line-height: 1.6; color: #909399; font-size: 12px">
26
+ 列表和详情模板需分别设置。当前页面模式只遮挡表单内容,顶部页签和左侧菜单仍可操作。
27
+ </div>
28
+ </el-form-item>
29
+ <el-form-item class="form-item-label-top" :label="i18nt('数据库表')">
17
30
  <el-input type="text" v-model="formConfig.entity"></el-input>
18
31
  </el-form-item>
19
32
  <el-form-item class="form-item-label-top" :label="i18nt('数据保存脚本编码')">
@@ -1273,8 +1286,16 @@ $\{wf.starterName\}提交的$\{pm_product_project.product_code\}$\{pm_product_pr
1273
1286
  this.designer.emitEvent("form-css-updated", deepClone(this.cssClassList));
1274
1287
  });
1275
1288
  },
1276
- computed: {
1277
- // formDialog/formDrawer 底部操作按钮配置(存 formConfig,随模板保存)
1289
+ computed: {
1290
+ dialogScopeValue: {
1291
+ get() {
1292
+ return this.formConfig.dialogScope === "page" ? "page" : "global";
1293
+ },
1294
+ set(value) {
1295
+ this.$set(this.formConfig, "dialogScope", value);
1296
+ },
1297
+ },
1298
+ // formDialog/formDrawer 底部操作按钮配置(存 formConfig,随模板保存)
1278
1299
  actionButtons() {
1279
1300
  return this.formConfig.actionButtons || [];
1280
1301
  },
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <el-form-item :label="i18nt('designer.setting.suffixIconClickable')">
3
+ <el-switch v-model="optionModel.suffixIconClickable"></el-switch>
4
+ </el-form-item>
5
+ </template>
6
+
7
+ <script>
8
+ import i18n from "../../../../../components/xform/utils/i18n"
9
+
10
+ export default {
11
+ name: "suffixIconClickable-editor",
12
+ mixins: [i18n],
13
+ props: {
14
+ designer: Object,
15
+ selectedWidget: Object,
16
+ optionModel: Object,
17
+ },
18
+ }
19
+ </script>
20
+
21
+ <style scoped>
22
+
23
+ </style>
@@ -211,6 +211,7 @@ const ADVANCED_PROPERTIES = {
211
211
  // 'showWordLimit': 'showWordLimit-editor',
212
212
  prefixIcon: "prefixIcon-editor",
213
213
  suffixIcon: "suffixIcon-editor",
214
+ suffixIconClickable: "suffixIconClickable-editor",
214
215
  switchWidth: "switchWidth-editor",
215
216
  activeText: "activeText-editor",
216
217
  inactiveText: "inactiveText-editor",
@@ -1202,6 +1202,7 @@ export const basicFields = [
1202
1202
  showWordLimit: !1,
1203
1203
  prefixIcon: "",
1204
1204
  suffixIcon: "",
1205
+ suffixIconClickable: !1,
1205
1206
  /*appendButton: !1,
1206
1207
  appendButtonDisabled: !1,
1207
1208
  buttonIcon: "el-icon-search",*/
@@ -55,6 +55,7 @@ import html2Canvas from "html2canvas";
55
55
  import JsPDF from "jspdf";
56
56
  import formulaDialog from "@base/components/xform/form-designer/form-widget/dialog/formulaDialog.vue";
57
57
  import baseFormulaDialog from "@base/components/xform/form-designer/form-widget/dialog/baseFormulaDialog.vue";
58
+ import { resolveDialogOption } from "@base/components/xform/form-render/pageDialogScope";
58
59
  import QRCode from "qrcode";
59
60
  import { openLuckysheetDialog } from "@base/components/luckysheet";
60
61
  import {
@@ -168,6 +169,10 @@ modules = {
168
169
  type: Boolean,
169
170
  default: false,
170
171
  },
172
+ dialogScope: {
173
+ type: String,
174
+ default: null,
175
+ },
171
176
  },
172
177
  provide() {
173
178
  let e = this;
@@ -5042,14 +5047,24 @@ modules = {
5042
5047
  }
5043
5048
  },*/
5044
5049
  openSearchDialog(option) {
5045
- this.searchDialogOption = option;
5050
+ this.searchDialogOption = resolveDialogOption(
5051
+ option,
5052
+ this.formJsonObj?.formConfig,
5053
+ this.dialogScope,
5054
+ this.$el
5055
+ );
5046
5056
  this.showSearchDialog = true;
5047
5057
  },
5048
5058
  confirmSearchDialog(rows) {
5049
5059
  this.searchDialogOption.confirm && this.searchDialogOption.confirm(rows);
5050
5060
  },
5051
5061
  openFormDialog(option) {
5052
- this.formDialogOption = option;
5062
+ this.formDialogOption = resolveDialogOption(
5063
+ option,
5064
+ this.formJsonObj?.formConfig,
5065
+ this.dialogScope,
5066
+ this.$el
5067
+ );
5053
5068
  this.showFormDialog = true;
5054
5069
  },
5055
5070
  closeFormDialog() {
@@ -0,0 +1,54 @@
1
+ export const PAGE_DIALOG_SCOPE = "page";
2
+
3
+ // 模板里的 top: "25vh" 是按整个窗口居中。当前页面弹框改由页面内容区 flex 居中,
4
+ // 再套视口 vh 会从内容区顶部再下移一截,弹框就偏下。px 等显式偏移仍保留。
5
+ export function pageDialogTop(top) {
6
+ const value = top == null ? "" : String(top).trim();
7
+ if (!value || /vh$/i.test(value)) return "0";
8
+ return value;
9
+ }
10
+
11
+ const PAGE_HOST_SELECTOR = "[data-xform-page-dialog-host]";
12
+
13
+ export function resolveDialogOption(option, formConfig, inheritedScope, element) {
14
+ const source = option || {};
15
+ const scope = source.dialogScope ?? formConfig?.dialogScope ?? inheritedScope;
16
+ if (scope !== PAGE_DIALOG_SCOPE) return source;
17
+
18
+ const host = element?.closest?.(PAGE_HOST_SELECTOR);
19
+ if (!host) {
20
+ console.warn("xform page dialog host not found; using global dialog");
21
+ return { ...source, dialogScope: "global" };
22
+ }
23
+ return { ...source, dialogScope: PAGE_DIALOG_SCOPE, pageDialogHost: host };
24
+ }
25
+
26
+ export const pageScopedDialogMixin = {
27
+ computed: {
28
+ isPageScope() {
29
+ return (
30
+ this.option?.dialogScope === PAGE_DIALOG_SCOPE
31
+ && !!this.option.pageDialogHost
32
+ );
33
+ },
34
+ pageDialogHasTop() {
35
+ return this.isPageScope && pageDialogTop(this.option.dialogConfig?.top) !== "0";
36
+ },
37
+ },
38
+ mounted() {
39
+ if (!this.isPageScope) return;
40
+ const dialog = this.$refs.pageDialog;
41
+ const wrapper = dialog?.$el;
42
+ const host = this.option.pageDialogHost;
43
+ if (!wrapper || !host) return;
44
+ host.appendChild(wrapper);
45
+ this.pageDialogWrapper = wrapper;
46
+ // The surrounding menu and route tabs remain interactive.
47
+ dialog.$refs.dialog?.setAttribute("aria-modal", "false");
48
+ },
49
+ beforeDestroy() {
50
+ const wrapper = this.pageDialogWrapper;
51
+ if (wrapper?.parentNode) wrapper.parentNode.removeChild(wrapper);
52
+ this.pageDialogWrapper = null;
53
+ },
54
+ };
@@ -299,6 +299,7 @@ export default {
299
299
  showWordLimit: "Show Word Limit",
300
300
  prefixIcon: "Prefix Icon",
301
301
  suffixIcon: "Suffix Icon",
302
+ suffixIconClickable: "Clickable Suffix Icon",
302
303
  inputButton: "Input Button Setting",
303
304
  appendButton: "Append Button",
304
305
  appendButtonDisabled: "Button Disabled",
@@ -463,6 +463,7 @@ export default {
463
463
  showWordLimit: "显示字数统计",
464
464
  prefixIcon: "头部Icon",
465
465
  suffixIcon: "尾部Icon",
466
+ suffixIconClickable: "尾部图标可点击",
466
467
  inputButton: "输入框按钮设置",
467
468
  appendButton: "添加后置按钮",
468
469
  appendButtonDisabled: "后置按钮禁用",
@@ -1128,6 +1128,7 @@ export function getDefaultFormConfig() {
1128
1128
  customClass: "",
1129
1129
  functions: "",
1130
1130
  layoutType: "PC",
1131
+ dialogScope: null,
1131
1132
  dataSources: [],
1132
1133
  onBeforeCreated: "",
1133
1134
  onFormCreated: "",
@@ -3,8 +3,9 @@ let modules = {};
3
3
 
4
4
  modules = {
5
5
  install: function(Vue) {
6
- Vue.directive('el-dialog-center', {
7
- bind(el, binding, vnode) {
6
+ Vue.directive('el-dialog-center', {
7
+ bind(el, binding, vnode) {
8
+ if (binding.value === false) return;
8
9
  if (el.children[0].querySelector(
9
10
  ".el-dialog__body")) {
10
11
  let autoTop = (document.body.offsetHeight - el.children[0]
@@ -18,10 +18,39 @@ modules = {
18
18
  }
19
19
  };
20
20
 
21
- dialogHeaderEl.onmousedown = function(e) {
22
- indexUtil.addClass(document.body, 'resize-ing');
23
-
24
- // 鼠标按下,计算当前元素距离可视区的距离
21
+ dialogHeaderEl.onmousedown = function(e) {
22
+ indexUtil.addClass(document.body, 'resize-ing');
23
+
24
+ if (el.classList.contains('xform-page-dialog-wrapper')) {
25
+ const hostRect = el.parentNode.getBoundingClientRect();
26
+ const dialogRect = dragDom.getBoundingClientRect();
27
+ const startX = e.clientX;
28
+ const startY = e.clientY;
29
+ const startLeft = parseFloat(getStyle(dragDom, 'left')) || 0;
30
+ const startTop = parseFloat(getStyle(dragDom, 'top')) || 0;
31
+
32
+ document.onmousemove = function(moveEvent) {
33
+ const deltaX = Math.min(
34
+ Math.max(moveEvent.clientX - startX, hostRect.left - dialogRect.left),
35
+ hostRect.right - dialogRect.right
36
+ );
37
+ const deltaY = Math.min(
38
+ Math.max(moveEvent.clientY - startY, hostRect.top - dialogRect.top),
39
+ hostRect.bottom - dialogRect.bottom
40
+ );
41
+ dragDom.style.left = startLeft + deltaX + 'px';
42
+ dragDom.style.top = startTop + deltaY + 'px';
43
+ vnode.child.$emit('dragDialog');
44
+ };
45
+ document.onmouseup = function() {
46
+ indexUtil.removeClass(document.body, 'resize-ing');
47
+ document.onmousemove = null;
48
+ document.onmouseup = null;
49
+ };
50
+ return;
51
+ }
52
+
53
+ // 鼠标按下,计算当前元素距离可视区的距离
25
54
  let disX = e.clientX - dialogHeaderEl.offsetLeft;
26
55
  let disY = e.clientY - dialogHeaderEl.offsetTop;
27
56
 
@@ -78,6 +78,97 @@ body {
78
78
  }
79
79
  }
80
80
  }
81
+
82
+ .app-main #containt.xform-page-dialog-host {
83
+ z-index: 0;
84
+ isolation: isolate;
85
+
86
+ > .xform-page-dialog-wrapper {
87
+ position: absolute !important;
88
+ inset: 0;
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+ background: transparent;
93
+ overflow: auto !important;
94
+
95
+ &.xform-page-dialog-wrapper--top {
96
+ align-items: flex-start;
97
+ }
98
+
99
+ > .el-dialog {
100
+ flex: none;
101
+ display: flex;
102
+ flex-direction: column;
103
+ max-width: calc(100% - 24px);
104
+ max-height: calc(100% - 24px);
105
+ margin-bottom: 0;
106
+
107
+ &.is-fullscreen {
108
+ max-width: 100%;
109
+ max-height: 100%;
110
+ }
111
+
112
+ > .el-dialog__body {
113
+ min-height: 0;
114
+ overflow: auto;
115
+ }
116
+ }
117
+
118
+ // 业务表单原先用视口 vh 给 .cont 定高。挂进当前页面后,可用高度变小,
119
+ // 需要让标题、内容、底栏按弹框自身高度分配,只在内容区滚动。
120
+ &.xform-page-form-dialog-wrapper {
121
+ overflow: hidden !important;
122
+
123
+ > .el-dialog {
124
+ overflow: hidden;
125
+
126
+ > .el-dialog__header,
127
+ > .el-dialog__footer {
128
+ flex: 0 0 auto;
129
+ }
130
+
131
+ > .el-dialog__body {
132
+ display: flex;
133
+ flex: 0 1 auto;
134
+ flex-direction: column;
135
+ height: auto !important;
136
+ min-height: 0;
137
+ overflow: hidden;
138
+
139
+ > .cont {
140
+ flex: 0 1 auto;
141
+ // 与全局业务弹框的常用高度一致;bodyConfig 的行内高度仍可覆盖。
142
+ height: 70vh;
143
+ min-height: 0;
144
+ overflow-x: hidden;
145
+ overflow-y: auto;
146
+ }
147
+
148
+ // 与旧版全局业务弹框一致,内容四周保留白色留白。
149
+ // 用边框承载留白,滚动时它不会像 padding 一样被卷走。
150
+ > .cont.designer-view:not(.fd-list-host) {
151
+ box-sizing: border-box;
152
+ border: 12px solid #fff;
153
+ padding: 0;
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ // 弹框挂进 #app 后,#containt.designer-view 的 background: none 会作用到弹框内容,
161
+ // 白底被去掉,露出页面底色。这里只把内容区白底加回来。
162
+ .el-dialog__body > #containt {
163
+ background-color: #fff;
164
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
165
+
166
+ &.designer-view {
167
+ background-color: #fff;
168
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
169
+ }
170
+ }
171
+ }
81
172
  /* 外链页面(#/outLinkView、#/form_outLinkView 等)不走 layout,没有 .app-main 撑高度,
82
173
  #containt 只能被内容撑开,列表/详情会塌陷显示不全,这里补上与 .app-main 一致的高度 */
83
174
  #app > #containt {
@@ -1,5 +1,16 @@
1
1
  <template>
2
- <div id="containt">
2
+ <div
3
+ id="containt"
4
+ :class="{
5
+ 'xform-page-dialog-host':
6
+ layoutType === 'PC' && !dialogScope && formConfig.dialogScope === 'page',
7
+ }"
8
+ :data-xform-page-dialog-host="
9
+ layoutType === 'PC' && !dialogScope && formConfig.dialogScope === 'page'
10
+ ? ''
11
+ : null
12
+ "
13
+ >
3
14
  <template v-if="layoutType === 'PC'">
4
15
  <x-tabs
5
16
  ref="xTabs"
@@ -22,6 +33,7 @@
22
33
  visible-key="showEdit"
23
34
  :visiable.sync="showEdit"
24
35
  :parent-target="_self"
36
+ :dialogScope="dialogScope"
25
37
  @reload="reload"
26
38
  @openCopyEditTab="openCopyEditTab"
27
39
  ></vFormRender>
@@ -40,6 +52,7 @@
40
52
  visible-key="showRender"
41
53
  :visiable.sync="showRender"
42
54
  :parent-target="_self"
55
+ :dialogScope="dialogScope"
43
56
  @reload="$reloadHandle"
44
57
  :openEditDialog="openEditDialog"
45
58
  ></vFormRender>
@@ -59,6 +72,7 @@
59
72
  :param="item.param"
60
73
  v-if="item.showContent"
61
74
  :parent-target="_self"
75
+ :dialogScope="dialogScope"
62
76
  @reload="(...args) => reloadAutoContent(...args)"
63
77
  :openEditDialog="openEditDialog1"
64
78
  ></vFormRender>
@@ -78,6 +92,7 @@
78
92
  :param="tab.param"
79
93
  v-if="tab.showContent"
80
94
  :parent-target="_self"
95
+ :dialogScope="dialogScope"
81
96
  @reload="(...args) => onEditTabReload(tab, ...args)"
82
97
  @openCopyEditTab="openCopyEditTab"
83
98
  ></vFormRender>
@@ -107,6 +122,7 @@
107
122
  v-if="showEditDialog && showEdit"
108
123
  visible-key="showEdit"
109
124
  :parent-target="_self"
125
+ :dialogScope="dialogScope"
110
126
  @reload="$reloadHandle"
111
127
  ></vFormRender>
112
128
  </div>
@@ -118,6 +134,7 @@
118
134
  v-if="showRender"
119
135
  visible-key="showRender"
120
136
  :parent-target="_self"
137
+ :dialogScope="dialogScope"
121
138
  @reload="$reloadHandle"
122
139
  :openEditDialog="openEditDialog"
123
140
  ></vFormRender>
@@ -131,6 +148,12 @@ import vFormRender from "../../../../views/user/form/vform/render";
131
148
  export default {
132
149
  name: "form_view:list",
133
150
  components: { vFormRender },
151
+ props: {
152
+ dialogScope: {
153
+ type: String,
154
+ default: null,
155
+ },
156
+ },
134
157
  mounted() {},
135
158
  data() {
136
159
  let that = this;