cloud-web-corejs 1.1.0-dev.19 → 1.1.0-dev.21

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 (22) hide show
  1. package/package.json +1 -1
  2. package/src/components/baseInputExport/mixins.js +0 -6
  3. package/src/components/xform/docs/2026-09 /345/212/250/346/200/201/345/255/227/346/256/265/350/247/204/345/210/231/344/270/216/346/265/201/347/250/213/346/216/247/345/210/266/346/211/247/350/241/214/351/241/272/345/272/217/350/220/275/345/234/260/346/226/271/346/241/210.md" +409 -0
  4. package/src/components/xform/form-designer/designer.js +2086 -2084
  5. package/src/components/xform/form-designer/form-widget/dialog/importDialogMixin.js +34 -0
  6. package/src/components/xform/form-designer/form-widget/field-widget/fieldMixin.js +13 -1
  7. package/src/components/xform/form-designer/setting-panel/form-dynamicField-setting.vue +687 -602
  8. package/src/components/xform/form-designer/setting-panel/form-setting.vue +74 -9
  9. package/src/components/xform/form-designer/setting-panel/property-editor/field-import-button/import2-button-editor.vue +8 -0
  10. package/src/components/xform/form-render/container-item/data-table-mixin.js +6304 -6285
  11. package/src/components/xform/form-render/container-item/dynamicFieldMixin.js +55 -1
  12. package/src/components/xform/form-render/container-item/tab-item.vue +138 -129
  13. package/src/components/xform/form-render/fieldControlEngine.js +218 -0
  14. package/src/components/xform/form-render/fieldControlMixin.js +534 -0
  15. package/src/components/xform/form-render/index.vue +164 -153
  16. package/src/components/xform/form-render/indexMixin.js +5415 -5331
  17. package/src/components/xform/mixins/defaultHandle.js +713 -707
  18. package/src/components/xform/utils/util.js +1710 -1708
  19. package/src/views/user/home/default.vue +6 -3
  20. package/src/views/user/home/wjl/content.vue +3 -2
  21. package/src/components/xform/form-render/container-item/dynamicFieldEngine.js +0 -285
  22. package/src/components/xform/form-render/formDynamicFieldMixin.js +0 -131
@@ -1,2084 +1,2086 @@
1
- /**
2
- * author: vformAdmin
3
- * email: vdpadmin@163.com
4
- * website: https://www.vform666.com
5
- * date: 2021.08.18
6
- * remark: 如果要分发VForm源码,需在本文件顶部保留此文件头信息!!
7
- */
8
-
9
- import {
10
- deepClone,
11
- generateId,
12
- getDefaultFormConfig,
13
- overwriteObj,
14
- createUUID,
15
- columnFormatMap,
16
- } from "../../../components/xform/utils/util";
17
- import { CLICK_BIND } from "./setting-panel/property-editor/field-button/clickBindActions";
18
- import {
19
- containers,
20
- advancedFields,
21
- basicFields,
22
- customFields,
23
- businessFields,
24
- } from "../../../components/xform/form-designer/widget-panel/widgetsConfig.js";
25
- import { VARIANT_FORM_VERSION } from "../../../components/xform/utils/config";
26
- import { keyNamePrefixMap } from "../../../components/xform/form-designer/widget-panel/widgetsConfig";
27
-
28
- let createDesigner0;
29
- const baseRefUtil = {
30
- deepClone,
31
- generateId,
32
- getDefaultFormConfig,
33
- overwriteObj,
34
- containers,
35
- advancedFields,
36
- basicFields,
37
- customFields,
38
- VARIANT_FORM_VERSION,
39
- };
40
-
41
- let chartContainers = [],
42
- chartWidgets = [];
43
-
44
- (function () {
45
- createDesigner0 = function (vueInstance) {
46
- let defaultFormConfig = baseRefUtil.deepClone(
47
- baseRefUtil.getDefaultFormConfig()
48
- );
49
-
50
- return {
51
- widgetList: [],
52
- formConfig: {
53
- cssCode: "",
54
- gridConfig: {
55
- accessReturnType: 1,
56
- isLoadDataByAccess: false,
57
- },
58
- scriptList: [],
59
- formType: 0,
60
- getConfig: {
61
- accessType: "1",
62
- accessUrl: null,
63
- accessParam: null,
64
- accessCallback: null,
65
- scriptName: null,
66
- scriptCode: null,
67
- },
68
- saveConfig: {
69
- accessType: "1",
70
- accessUrl: null,
71
- accessParam: null,
72
- accessCallback: null,
73
- scriptName: null,
74
- scriptCode: null,
75
- },
76
- editFormCode: null,
77
- editFormName: null,
78
- searchDialogNameField: null,
79
- searchDialogUniqueField: null,
80
- entity: null,
81
- wfEnabled: false,
82
- isLoadEntity: false,
83
- formScriptCode: "getOne",
84
- formScriptParam: null,
85
- formScriptSuccess: null,
86
- saveScriptCode: "saveUpdate",
87
- wfConfig: null,
88
- wfStartBindSave: false,
89
- wfStartConfirmText: null,
90
- wfAgreenBindSave: false,
91
- wfAgreeConfigData: [],
92
- wfConfigDataEnabled: false,
93
- wfConfigData: [],
94
- multiTabEnabled: false,
95
- multiTabLabelField: null,
96
- addTabEnabled: false, // 新增打开独立页签(不走「常规」页签)
97
- submitBehavior: "refreshCurrent", // 提交后行为: refreshCurrent(默认,留在详情页) | closeToList
98
- billNavEnabled: false, // 详情页签显示「上一单/下一单」翻单按钮
99
- addFormCode: null,
100
- addFormName: null,
101
- wfTheme: null,
102
- otherTabEnabled: false,
103
- otherTabList: [],
104
- hideNormalTab: false,
105
- customListTabLabel: null,
106
- globalConfig: null,
107
- // 表单级动态字段规则
108
- dynamicFieldEnabled: false,
109
- dynamicFieldSourceType: "local",
110
- dynamicFieldRules: [],
111
- dynamicFieldScriptCode: null,
112
- dynamicFieldScriptParam: null,
113
- dynamicFieldTriggerFields: [],
114
- },
115
- dataSources: [], //数据源
116
-
117
- selectedId: null,
118
- selectedWidget: null,
119
- selectedWidgetName: null, //选中组件名称(唯一)
120
- vueInstance: vueInstance,
121
-
122
- formWidget: null, //表单设计容器
123
-
124
- cssClassList: [], //自定义样式列表
125
-
126
- historyData: {
127
- index: -1, //index: 0,
128
- maxStep: 20,
129
- steps: [],
130
- },
131
-
132
- initDesigner(resetFormJson) {
133
- this.widgetList = [];
134
- this.formConfig = baseRefUtil.deepClone(defaultFormConfig);
135
- this.dataSources = [];
136
-
137
- //输出版本信息和语雀链接
138
- /* console.info(`%cVariantForm %cVer${baseRefUtil.VARIANT_FORM_VERSION} %chttps://www.yuque.com/visualdev/vform`,
139
- "color:#409EFF;font-size: 22px;font-weight:bolder",
140
- "color:#999;font-size: 12px",
141
- "color:#333"
142
- ); */
143
-
144
- /*if (!resetFormJson) {
145
- this.initHistoryData();
146
- }*/
147
- },
148
-
149
- clearDesigner(skipHistoryChange) {
150
- let emptyWidgetListFlag = this.widgetList.length === 0;
151
- /* 版式是"当前在设计哪一端",不是表单内容的一部分。defaultFormConfig 里没有
152
- layoutType,overwriteObj 之后 getLayoutType() 会退回 "PC" —— 在 H5 模板里
153
- 点一下「清空」,左侧面板就跳回 PC 组件列表了。先存后还。 */
154
- let keepLayoutType = this.getLayoutType();
155
- this.widgetList = [];
156
- this.selectedId = null;
157
- this.selectedWidgetName = null;
158
- this.selectedWidget = {}; //this.selectedWidget = null
159
- baseRefUtil.overwriteObj(this.formConfig, defaultFormConfig); //
160
- this.formConfig.gridConfig = defaultFormConfig.gridConfig;
161
- this.formConfig.layoutType = keepLayoutType;
162
-
163
- if (!!skipHistoryChange) {
164
- //什么也不做!!
165
- } else if (!emptyWidgetListFlag) {
166
- this.emitHistoryChange();
167
- } else {
168
- this.saveCurrentHistoryStep();
169
- }
170
- },
171
-
172
- loadPresetCssCode(preCssCode) {
173
- if (this.formConfig.cssCode === "" && !!preCssCode) {
174
- this.formConfig.cssCode = preCssCode;
175
- }
176
- },
177
-
178
- getLayoutType() {
179
- return this.formConfig.layoutType || "PC";
180
- },
181
-
182
- changeLayoutType(newType) {
183
- this.formConfig.layoutType = newType;
184
- },
185
-
186
- getImportTemplate() {
187
- return {
188
- widgetList: [],
189
- // formConfig: baseRefUtil.deepClone(this.formConfig)
190
- formConfig: baseRefUtil.deepClone(defaultFormConfig),
191
- };
192
- },
193
-
194
- handleImportJson(formJson) {
195
- let formConfig = formJson.formConfig;
196
- if (formConfig.formCode === vueInstance?.reportTemplate?.formCode) {
197
- return;
198
- }
199
- let widgetArr = formJson.widgetList;
200
- let itemFieldMap = {
201
- grid: "cols",
202
- table: "rows",
203
- "table-cell": "widgetList",
204
- "h5-table": "rows",
205
- "h5-table-cell": "widgetList",
206
- tab: "tabs",
207
- "tab-pane": "widgetList",
208
- "grid-col": "widgetList",
209
- "vf-box": "widgetList",
210
- card: "widgetList",
211
- detail: "panes",
212
- "detail-plain": "panes",
213
- "detail-pane": "widgetList",
214
- "detail-h5": "panes",
215
- "h5-card": "panes",
216
- "h5-card-pane": "widgetList",
217
- };
218
- let loopDo = (widgetList) => {
219
- if (!widgetList) return;
220
- widgetList.forEach((widget) => {
221
- if (widget.type === "data-table" || widget.type === "list-h5") {
222
- let vailColumns = widget.options.tableColumns.filter(
223
- (item) => item.prop && item.label
224
- );
225
- vailColumns.forEach((item) => {
226
- if (item.formatS === "editAttachment") {
227
- let prop = item.prop;
228
- let columnOption = item.columnOption;
229
- let editColumnOption = item.editColumnOption;
230
-
231
- let suffix = this.createAttachmentSuffix();
232
- let keyName = this.createAttachmentKeyName(suffix);
233
- if (columnOption) {
234
- columnOption.keyName = keyName;
235
- columnOption.keyNameSuffix = suffix;
236
- }
237
- if (editColumnOption) {
238
- editColumnOption.keyName = keyName;
239
- editColumnOption.keyNameSuffix = suffix;
240
- }
241
- item.prop = keyName;
242
- }
243
- });
244
- } else if (
245
- widget.type === "vabUpload" ||
246
- widget.type === "baseAttachment"
247
- ) {
248
- let suffix = this.createAttachmentSuffix();
249
- let keyName = this.createAttachmentKeyName(suffix);
250
- widget.options.keyName = keyName;
251
- widget.options.keyNameSuffix = suffix;
252
- } else {
253
- if (widget.category === "container") {
254
- let itemField = itemFieldMap[widget.type];
255
- if (itemField) {
256
- if ("table" === widget.type) {
257
- widget[itemField].forEach((item) => {
258
- loopDo(item.cols);
259
- });
260
- } else if ("h5-table" === widget.type) {
261
- widget[itemField].forEach((item) => {
262
- loopDo(item.cols);
263
- });
264
- } else {
265
- loopDo(widget[itemField]);
266
- }
267
- }
268
- }
269
- }
270
- });
271
- };
272
- loopDo(widgetArr);
273
- },
274
- loadFormJson(formJson) {
275
- let modifiedFlag = false;
276
-
277
- if (!!formJson && !!formJson.widgetList) {
278
- this.widgetList = formJson.widgetList;
279
- modifiedFlag = true;
280
- }
281
- if (!!formJson && !!formJson.formConfig) {
282
- //this.formConfig = importObj.formConfig
283
- baseRefUtil.overwriteObj(
284
- this.formConfig,
285
- formJson.formConfig
286
- ); /* 用=赋值,会导致inject依赖注入的formConfig属性变成非响应式 */
287
- modifiedFlag = true;
288
- }
289
-
290
- if (modifiedFlag) {
291
- this.emitEvent("form-json-imported", []); // 通知其他组件
292
- }
293
- this.setSelected();
294
- return modifiedFlag;
295
- },
296
- handleSelectedWidget(selected) {
297
- //处理历史未定义的属性
298
- if (selected.formItemFlag || selected.type === "data-table") {
299
- if (selected.options.submitFlag === void 0) {
300
- // selected.options.submitFlag = true;
301
- this.vueInstance.$set(selected.options, "submitFlag", true);
302
- }
303
- }
304
- this.handleKeyNameSuffix(selected);
305
- },
306
- handleKeyNameSuffix(selected) {
307
- if (!selected) return;
308
- let optionModel = selected.options;
309
- let prefix = this.getKeyNamePrefix(selected.type, optionModel);
310
- if (
311
- optionModel.keyNameEnabled &&
312
- !!prefix &&
313
- !optionModel.keyNameSuffix
314
- ) {
315
- let keyName = optionModel.keyName;
316
- if (keyName.startsWith(prefix)) {
317
- this.vueInstance.$set(
318
- optionModel,
319
- "keyNameSuffix",
320
- keyName.substring(prefix.length)
321
- );
322
- }
323
- }
324
- },
325
- setSelected(selected) {
326
- if (!selected) {
327
- this.clearSelected();
328
- return;
329
- }
330
-
331
- //处理历史未定义的属性
332
- this.handleSelectedWidget(selected);
333
-
334
- this.selectedWidget = selected;
335
- if (!!selected.id) {
336
- this.selectedId = selected.id;
337
- this.selectedWidgetName = selected.options.name;
338
- if (!selected.category) {
339
- this.emitEvent("canvas-select-field", selected.options.name);
340
- } else {
341
- this.emitEvent("canvas-select-container", selected.options.name);
342
- }
343
- }
344
- },
345
-
346
- updateSelectedWidgetNameAndLabel(selectedWidget, newName, newLabel) {
347
- this.selectedWidgetName = newName;
348
- //selectedWidget.options.name = newName //此行多余
349
- if (
350
- !!newLabel &&
351
- Object.keys(selectedWidget.options).indexOf("label") > -1
352
- ) {
353
- selectedWidget.options.label = newLabel;
354
- }
355
- },
356
-
357
- clearSelected() {
358
- this.selectedId = null;
359
- this.selectedWidgetName = null;
360
- this.selectedWidget = {}; //this.selectedWidget = null
361
- },
362
-
363
- checkWidgetMove(evt) {
364
- /* Only field widget can be dragged into sub-form */
365
- if (!!evt.draggedContext && !!evt.draggedContext.element) {
366
- let wgCategory = evt.draggedContext.element.category;
367
- let wgType = evt.draggedContext.element.type;
368
- if (!!evt.to) {
369
- if (
370
- evt.to.className === "sub-form-table" &&
371
- wgCategory === "container"
372
- ) {
373
- //this.$message.info(this.vueInstance.i18nt('designer.hint.onlyFieldWidgetAcceptable'))
374
- return false;
375
- }
376
- }
377
- }
378
-
379
- return true;
380
- },
381
-
382
- checkFieldMove(evt) {
383
- if (!!evt.draggedContext && !!evt.draggedContext.element) {
384
- let wgCategory = evt.draggedContext.element.category;
385
- let wgType = evt.draggedContext.element.type + "";
386
- //console.log('wgType======', wgType)
387
- if (!!evt.to) {
388
- if (evt.to.className === "sub-form-table" && wgType === "slot") {
389
- //this.$message.info(this.vueInstance.i18nt('designer.hint.onlyFieldWidgetAcceptable'))
390
- return false;
391
- }
392
- }
393
- }
394
-
395
- return true;
396
- },
397
-
398
- /**
399
- * 追加表格新行
400
- * @param widget
401
- */
402
- appendTableRow(widget) {
403
- let rowIdx = widget.rows.length; //确定插入行位置
404
- let newRow = baseRefUtil.deepClone(widget.rows[widget.rows.length - 1]);
405
- newRow.id = "table-row-" + baseRefUtil.generateId();
406
- newRow.merged = false;
407
- newRow.cols.forEach((col) => {
408
- col.id = "table-cell-" + baseRefUtil.generateId();
409
- col.options.name = col.id;
410
- col.merged = false;
411
- col.options.colspan = 1;
412
- col.options.rowspan = 1;
413
- col.widgetList.length = 0;
414
- });
415
- widget.rows.splice(rowIdx, 0, newRow);
416
-
417
- this.emitHistoryChange();
418
- },
419
-
420
- /**
421
- * 追加表格新列
422
- * @param widget
423
- */
424
- appendTableCol(widget) {
425
- let colIdx = widget.rows[0].cols.length; //确定插入列位置
426
- widget.rows.forEach((row) => {
427
- let newCol = baseRefUtil.deepClone(
428
- this.getContainerByType("table-cell")
429
- );
430
- newCol.id = "table-cell-" + baseRefUtil.generateId();
431
- newCol.options.name = newCol.id;
432
- newCol.merged = false;
433
- newCol.options.colspan = 1;
434
- newCol.options.rowspan = 1;
435
- newCol.widgetList.length = 0;
436
- row.cols.splice(colIdx, 0, newCol);
437
- });
438
-
439
- this.emitHistoryChange();
440
- },
441
-
442
- insertTableRow(widget, insertPos, cloneRowIdx, curCol, aboveFlag) {
443
- let newRowIdx = !!aboveFlag ? insertPos : insertPos + 1; //初步确定插入行位置
444
- if (!aboveFlag) {
445
- //继续向下寻找同列第一个未被合并的单元格
446
- let tmpRowIdx = newRowIdx;
447
- let rowFoundFlag = false;
448
- while (tmpRowIdx < widget.rows.length) {
449
- if (!widget.rows[tmpRowIdx].cols[curCol].merged) {
450
- newRowIdx = tmpRowIdx;
451
- rowFoundFlag = true;
452
- break;
453
- } else {
454
- tmpRowIdx++;
455
- }
456
- }
457
-
458
- if (!rowFoundFlag) {
459
- newRowIdx = widget.rows.length;
460
- }
461
- }
462
-
463
- let newRow = baseRefUtil.deepClone(widget.rows[cloneRowIdx]);
464
- newRow.id = "table-row-" + baseRefUtil.generateId();
465
- newRow.merged = false;
466
- newRow.cols.forEach((col) => {
467
- col.id = "table-cell-" + baseRefUtil.generateId();
468
- col.options.name = col.id;
469
- col.merged = false;
470
- col.options.colspan = 1;
471
- col.options.rowspan = 1;
472
- col.widgetList.length = 0;
473
- });
474
- widget.rows.splice(newRowIdx, 0, newRow);
475
-
476
- let colNo = 0;
477
- while (
478
- newRowIdx < widget.rows.length - 1 &&
479
- colNo < widget.rows[0].cols.length
480
- ) {
481
- //越界判断
482
- const cellOfNextRow = widget.rows[newRowIdx + 1].cols[colNo];
483
- const rowMerged = cellOfNextRow.merged; //确定插入位置下一行的单元格是否为合并单元格
484
- if (!!rowMerged) {
485
- let rowArray = widget.rows;
486
- let unMergedCell = {};
487
- let startRowIndex = null;
488
- for (let i = newRowIdx; i >= 0; i--) {
489
- //查找该行已合并的主单元格
490
- if (
491
- !rowArray[i].cols[colNo].merged &&
492
- rowArray[i].cols[colNo].options.rowspan > 1
493
- ) {
494
- startRowIndex = i;
495
- unMergedCell = rowArray[i].cols[colNo];
496
- break;
497
- }
498
- }
499
-
500
- if (!!unMergedCell.options) {
501
- //如果有符合条件的unMergedCell
502
- let newRowspan = unMergedCell.options.rowspan + 1;
503
- this.setPropsOfMergedRows(
504
- widget.rows,
505
- startRowIndex,
506
- colNo,
507
- unMergedCell.options.colspan,
508
- newRowspan
509
- );
510
- colNo += unMergedCell.options.colspan;
511
- } else {
512
- colNo += 1;
513
- }
514
- } else {
515
- //colNo += 1
516
- colNo += cellOfNextRow.options.colspan || 1;
517
- }
518
- }
519
-
520
- this.emitHistoryChange();
521
- },
522
-
523
- insertTableCol(widget, insertPos, curRow, leftFlag) {
524
- let newColIdx = !!leftFlag ? insertPos : insertPos + 1; //初步确定插入列位置
525
- if (!leftFlag) {
526
- //继续向右寻找同行第一个未被合并的单元格
527
- let tmpColIdx = newColIdx;
528
- let colFoundFlag = false;
529
- while (tmpColIdx < widget.rows[curRow].cols.length) {
530
- if (!widget.rows[curRow].cols[tmpColIdx].merged) {
531
- newColIdx = tmpColIdx;
532
- colFoundFlag = true;
533
- break;
534
- } else {
535
- tmpColIdx++;
536
- }
537
-
538
- if (!colFoundFlag) {
539
- newColIdx = widget.rows[curRow].cols.length;
540
- }
541
- }
542
- }
543
-
544
- widget.rows.forEach((row) => {
545
- let newCol = baseRefUtil.deepClone(
546
- this.getContainerByType("table-cell")
547
- );
548
- newCol.id = "table-cell-" + baseRefUtil.generateId();
549
- newCol.options.name = newCol.id;
550
- newCol.merged = false;
551
- newCol.options.colspan = 1;
552
- newCol.options.rowspan = 1;
553
- newCol.widgetList.length = 0;
554
- row.cols.splice(newColIdx, 0, newCol);
555
- });
556
-
557
- let rowNo = 0;
558
- while (
559
- newColIdx < widget.rows[0].cols.length - 1 &&
560
- rowNo < widget.rows.length
561
- ) {
562
- //越界判断
563
- const cellOfNextCol = widget.rows[rowNo].cols[newColIdx + 1];
564
- const colMerged = cellOfNextCol.merged; //确定插入位置右侧列的单元格是否为合并单元格
565
- if (!!colMerged) {
566
- let colArray = widget.rows[rowNo].cols;
567
- let unMergedCell = {};
568
- let startColIndex = null;
569
- for (let i = newColIdx; i >= 0; i--) {
570
- //查找该行已合并的主单元格
571
- if (!colArray[i].merged && colArray[i].options.colspan > 1) {
572
- startColIndex = i;
573
- unMergedCell = colArray[i];
574
- break;
575
- }
576
- }
577
-
578
- if (!!unMergedCell.options) {
579
- //如果有符合条件的unMergedCell
580
- let newColspan = unMergedCell.options.colspan + 1;
581
- this.setPropsOfMergedCols(
582
- widget.rows,
583
- rowNo,
584
- startColIndex,
585
- newColspan,
586
- unMergedCell.options.rowspan
587
- );
588
- rowNo += unMergedCell.options.rowspan;
589
- } else {
590
- rowNo += 1;
591
- }
592
- } else {
593
- //rowNo += 1
594
- rowNo += cellOfNextCol.options.rowspan || 1;
595
- }
596
- }
597
-
598
- this.emitHistoryChange();
599
- },
600
- insertH5TableCol(widget, insertPos, curRow, leftFlag) {
601
- let newColIdx = !!leftFlag ? insertPos : insertPos + 1; //初步确定插入列位置
602
- if (!leftFlag) {
603
- //继续向右寻找同行第一个未被合并的单元格
604
- let tmpColIdx = newColIdx;
605
- let colFoundFlag = false;
606
- while (tmpColIdx < widget.rows[curRow].cols.length) {
607
- if (!widget.rows[curRow].cols[tmpColIdx].merged) {
608
- newColIdx = tmpColIdx;
609
- colFoundFlag = true;
610
- break;
611
- } else {
612
- tmpColIdx++;
613
- }
614
-
615
- if (!colFoundFlag) {
616
- newColIdx = widget.rows[curRow].cols.length;
617
- }
618
- }
619
- }
620
-
621
- widget.rows.forEach((row) => {
622
- let newCol = baseRefUtil.deepClone(
623
- this.getContainerByType("h5-table-cell")
624
- );
625
- newCol.id = "table-cell-" + baseRefUtil.generateId();
626
- newCol.options.name = newCol.id;
627
- newCol.merged = false;
628
- newCol.options.colspan = 1;
629
- newCol.options.rowspan = 1;
630
- newCol.widgetList.length = 0;
631
- row.cols.splice(newColIdx, 0, newCol);
632
- });
633
-
634
- let rowNo = 0;
635
- while (
636
- newColIdx < widget.rows[0].cols.length - 1 &&
637
- rowNo < widget.rows.length
638
- ) {
639
- //越界判断
640
- const cellOfNextCol = widget.rows[rowNo].cols[newColIdx + 1];
641
- const colMerged = cellOfNextCol.merged; //确定插入位置右侧列的单元格是否为合并单元格
642
- if (!!colMerged) {
643
- let colArray = widget.rows[rowNo].cols;
644
- let unMergedCell = {};
645
- let startColIndex = null;
646
- for (let i = newColIdx; i >= 0; i--) {
647
- //查找该行已合并的主单元格
648
- if (!colArray[i].merged && colArray[i].options.colspan > 1) {
649
- startColIndex = i;
650
- unMergedCell = colArray[i];
651
- break;
652
- }
653
- }
654
-
655
- if (!!unMergedCell.options) {
656
- //如果有符合条件的unMergedCell
657
- let newColspan = unMergedCell.options.colspan + 1;
658
- this.setPropsOfMergedCols(
659
- widget.rows,
660
- rowNo,
661
- startColIndex,
662
- newColspan,
663
- unMergedCell.options.rowspan
664
- );
665
- rowNo += unMergedCell.options.rowspan;
666
- } else {
667
- rowNo += 1;
668
- }
669
- } else {
670
- //rowNo += 1
671
- rowNo += cellOfNextCol.options.rowspan || 1;
672
- }
673
- }
674
-
675
- this.emitHistoryChange();
676
- },
677
- setPropsOfMergedCols(
678
- rowArray,
679
- startRowIndex,
680
- startColIndex,
681
- newColspan,
682
- rowspan
683
- ) {
684
- for (let i = startRowIndex; i < startRowIndex + rowspan; i++) {
685
- for (let j = startColIndex; j < startColIndex + newColspan; j++) {
686
- if (i === startRowIndex && j === startColIndex) {
687
- rowArray[i].cols[j].options.colspan = newColspan; //合并后的主单元格
688
- continue;
689
- }
690
-
691
- rowArray[i].cols[j].merged = true;
692
- rowArray[i].cols[j].options.colspan = newColspan;
693
- rowArray[i].cols[j].widgetList = [];
694
- }
695
- }
696
- },
697
-
698
- setPropsOfMergedRows(
699
- rowArray,
700
- startRowIndex,
701
- startColIndex,
702
- colspan,
703
- newRowspan
704
- ) {
705
- for (let i = startRowIndex; i < startRowIndex + newRowspan; i++) {
706
- for (let j = startColIndex; j < startColIndex + colspan; j++) {
707
- if (i === startRowIndex && j === startColIndex) {
708
- rowArray[i].cols[j].options.rowspan = newRowspan;
709
- continue;
710
- }
711
-
712
- rowArray[i].cols[j].merged = true;
713
- rowArray[i].cols[j].options.rowspan = newRowspan;
714
- rowArray[i].cols[j].widgetList = [];
715
- }
716
- }
717
- },
718
-
719
- setPropsOfSplitCol(
720
- rowArray,
721
- startRowIndex,
722
- startColIndex,
723
- colspan,
724
- rowspan
725
- ) {
726
- for (let i = startRowIndex; i < startRowIndex + rowspan; i++) {
727
- for (let j = startColIndex; j < startColIndex + colspan; j++) {
728
- rowArray[i].cols[j].merged = false;
729
- rowArray[i].cols[j].options.rowspan = 1;
730
- rowArray[i].cols[j].options.colspan = 1;
731
- }
732
- }
733
- },
734
-
735
- setPropsOfSplitRow(
736
- rowArray,
737
- startRowIndex,
738
- startColIndex,
739
- colspan,
740
- rowspan
741
- ) {
742
- for (let i = startRowIndex; i < startRowIndex + rowspan; i++) {
743
- for (let j = startColIndex; j < startColIndex + colspan; j++) {
744
- rowArray[i].cols[j].merged = false;
745
- rowArray[i].cols[j].options.rowspan = 1;
746
- rowArray[i].cols[j].options.colspan = 1;
747
- }
748
- }
749
- },
750
-
751
- mergeTableCol(rowArray, colArray, curRow, curCol, leftFlag, cellWidget) {
752
- let mergedColIdx = !!leftFlag
753
- ? curCol
754
- : curCol + colArray[curCol].options.colspan;
755
-
756
- // let remainedColIdx = !!leftFlag ? curCol - colArray[curCol - 1].options.colspan : curCol
757
- let remainedColIdx = !!leftFlag ? curCol - 1 : curCol;
758
- if (!!leftFlag) {
759
- //继续向左寻找同行未被合并的第一个单元格
760
- let tmpColIdx = remainedColIdx;
761
- while (tmpColIdx >= 0) {
762
- if (!rowArray[curRow].cols[tmpColIdx].merged) {
763
- remainedColIdx = tmpColIdx;
764
- break;
765
- } else {
766
- tmpColIdx--;
767
- }
768
- }
769
- }
770
-
771
- if (
772
- !!colArray[mergedColIdx].widgetList &&
773
- colArray[mergedColIdx].widgetList.length > 0
774
- ) {
775
- //保留widgetList
776
- if (
777
- !colArray[remainedColIdx].widgetList ||
778
- colArray[remainedColIdx].widgetList.length === 0
779
- ) {
780
- colArray[remainedColIdx].widgetList = baseRefUtil.deepClone(
781
- colArray[mergedColIdx].widgetList
782
- );
783
- }
784
- }
785
-
786
- let newColspan =
787
- colArray[mergedColIdx].options.colspan * 1 +
788
- colArray[remainedColIdx].options.colspan * 1;
789
- this.setPropsOfMergedCols(
790
- rowArray,
791
- curRow,
792
- remainedColIdx,
793
- newColspan,
794
- cellWidget.options.rowspan
795
- );
796
-
797
- this.emitHistoryChange();
798
- },
799
-
800
- mergeTableWholeRow(rowArray, colArray, rowIndex, colIndex) {
801
- //需要考虑操作的行存在已合并的单元格!!
802
- //整行所有单元格行高不一致不可合并!!
803
- let startRowspan = rowArray[rowIndex].cols[0].options.rowspan;
804
- let unmatchedFlag = false;
805
- for (let i = 1; i < rowArray[rowIndex].cols.length; i++) {
806
- if (rowArray[rowIndex].cols[i].options.rowspan !== startRowspan) {
807
- unmatchedFlag = true;
808
- break;
809
- }
810
- }
811
- if (unmatchedFlag) {
812
- this.vueInstance.$message.info(
813
- this.vueInstance.i18nt(
814
- "designer.hint.rowspanNotConsistentForMergeEntireRow"
815
- )
816
- );
817
- return;
818
- }
819
-
820
- let widgetListCols = colArray.filter((colItem) => {
821
- return (
822
- !colItem.merged &&
823
- !!colItem.widgetList &&
824
- colItem.widgetList.length > 0
825
- );
826
- });
827
- if (!!widgetListCols && widgetListCols.length > 0) {
828
- //保留widgetList
829
- if (
830
- widgetListCols[0].id !== colArray[0].id &&
831
- (!colArray[0].widgetList || colArray[0].widgetList.length <= 0)
832
- ) {
833
- colArray[0].widgetList = baseRefUtil.deepClone(
834
- widgetListCols[0].widgetList
835
- );
836
- }
837
- }
838
-
839
- this.setPropsOfMergedCols(
840
- rowArray,
841
- rowIndex,
842
- 0,
843
- colArray.length,
844
- colArray[colIndex].options.rowspan
845
- );
846
-
847
- this.emitHistoryChange();
848
- },
849
-
850
- mergeTableRow(rowArray, curRow, curCol, aboveFlag, cellWidget) {
851
- let mergedRowIdx = !!aboveFlag
852
- ? curRow
853
- : curRow + cellWidget.options.rowspan;
854
-
855
- //let remainedRowIdx = !!aboveFlag ? curRow - cellWidget.options.rowspan : curRow
856
- let remainedRowIdx = !!aboveFlag ? curRow - 1 : curRow;
857
- if (!!aboveFlag) {
858
- //继续向上寻找同列未被合并的第一个单元格
859
- let tmpRowIdx = remainedRowIdx;
860
- while (tmpRowIdx >= 0) {
861
- if (!rowArray[tmpRowIdx].cols[curCol].merged) {
862
- remainedRowIdx = tmpRowIdx;
863
- break;
864
- } else {
865
- tmpRowIdx--;
866
- }
867
- }
868
- }
869
-
870
- if (
871
- !!rowArray[mergedRowIdx].cols[curCol].widgetList &&
872
- rowArray[mergedRowIdx].cols[curCol].widgetList.length > 0
873
- ) {
874
- //保留widgetList
875
- if (
876
- !rowArray[remainedRowIdx].cols[curCol].widgetList ||
877
- rowArray[remainedRowIdx].cols[curCol].widgetList.length === 0
878
- ) {
879
- rowArray[remainedRowIdx].cols[curCol].widgetList =
880
- baseRefUtil.deepClone(
881
- rowArray[mergedRowIdx].cols[curCol].widgetList
882
- );
883
- }
884
- }
885
-
886
- let newRowspan =
887
- rowArray[mergedRowIdx].cols[curCol].options.rowspan * 1 +
888
- rowArray[remainedRowIdx].cols[curCol].options.rowspan * 1;
889
- this.setPropsOfMergedRows(
890
- rowArray,
891
- remainedRowIdx,
892
- curCol,
893
- cellWidget.options.colspan,
894
- newRowspan
895
- );
896
-
897
- this.emitHistoryChange();
898
- },
899
-
900
- mergeTableWholeCol(rowArray, colArray, rowIndex, colIndex) {
901
- //需要考虑操作的列存在已合并的单元格!!
902
- //整列所有单元格列宽不一致不可合并!!
903
- let startColspan = rowArray[0].cols[colIndex].options.colspan;
904
- let unmatchedFlag = false;
905
- for (let i = 1; i < rowArray.length; i++) {
906
- if (rowArray[i].cols[colIndex].options.colspan !== startColspan) {
907
- unmatchedFlag = true;
908
- break;
909
- }
910
- }
911
- if (unmatchedFlag) {
912
- this.vueInstance.$message.info(
913
- this.vueInstance.i18nt(
914
- "designer.hint.colspanNotConsistentForMergeEntireColumn"
915
- )
916
- );
917
- return;
918
- }
919
-
920
- let widgetListCols = [];
921
- rowArray.forEach((rowItem) => {
922
- let tempCell = rowItem.cols[colIndex];
923
- if (
924
- !tempCell.merged &&
925
- !!tempCell.widgetList &&
926
- tempCell.widgetList.length > 0
927
- ) {
928
- widgetListCols.push(tempCell);
929
- }
930
- });
931
-
932
- let firstCellOfCol = rowArray[0].cols[colIndex];
933
- if (!!widgetListCols && widgetListCols.length > 0) {
934
- //保留widgetList
935
- if (
936
- widgetListCols[0].id !== firstCellOfCol.id &&
937
- (!firstCellOfCol.widgetList ||
938
- firstCellOfCol.widgetList.length <= 0)
939
- ) {
940
- firstCellOfCol.widgetList = baseRefUtil.deepClone(
941
- widgetListCols[0].widgetList
942
- );
943
- }
944
- }
945
-
946
- this.setPropsOfMergedRows(
947
- rowArray,
948
- 0,
949
- colIndex,
950
- firstCellOfCol.options.colspan,
951
- rowArray.length
952
- );
953
-
954
- this.emitHistoryChange();
955
- },
956
-
957
- undoMergeTableCol(rowArray, rowIndex, colIndex, colspan, rowspan) {
958
- this.setPropsOfSplitCol(rowArray, rowIndex, colIndex, colspan, rowspan);
959
-
960
- this.emitHistoryChange();
961
- },
962
-
963
- undoMergeTableRow(rowArray, rowIndex, colIndex, colspan, rowspan) {
964
- this.setPropsOfSplitRow(rowArray, rowIndex, colIndex, colspan, rowspan);
965
-
966
- this.emitHistoryChange();
967
- },
968
-
969
- deleteTableWholeCol(rowArray, colIndex) {
970
- //需考虑删除的是合并列!!
971
- let onlyOneColFlag = true;
972
- rowArray.forEach((ri) => {
973
- if (ri.cols[0].options.colspan !== rowArray[0].cols.length) {
974
- onlyOneColFlag = false;
975
- }
976
- });
977
- //仅剩一列则不可删除!!
978
- if (onlyOneColFlag) {
979
- this.vueInstance.$message.info(
980
- this.vueInstance.i18nt("designer.hint.lastColCannotBeDeleted")
981
- );
982
- return;
983
- }
984
-
985
- //整列所有单元格列宽不一致不可删除!!
986
- let startColspan = rowArray[0].cols[colIndex].options.colspan;
987
- let unmatchedFlag = false;
988
- for (let i = 1; i < rowArray.length; i++) {
989
- if (rowArray[i].cols[colIndex].options.colspan !== startColspan) {
990
- unmatchedFlag = true;
991
- break;
992
- }
993
- }
994
- if (unmatchedFlag) {
995
- this.vueInstance.$message.info(
996
- this.vueInstance.i18nt(
997
- "designer.hint.colspanNotConsistentForDeleteEntireColumn"
998
- )
999
- );
1000
- return;
1001
- }
1002
-
1003
- rowArray.forEach((rItem) => {
1004
- rItem.cols.splice(colIndex, startColspan);
1005
- });
1006
-
1007
- this.emitHistoryChange();
1008
- },
1009
-
1010
- deleteTableWholeRow(rowArray, rowIndex) {
1011
- //需考虑删除的是合并行!!
1012
- let onlyOneRowFlag = true;
1013
- rowArray[0].cols.forEach((ci) => {
1014
- if (ci.options.rowspan !== rowArray.length) {
1015
- onlyOneRowFlag = false;
1016
- }
1017
- });
1018
- //仅剩一行则不可删除!!
1019
- if (onlyOneRowFlag) {
1020
- this.vueInstance.$message.info(
1021
- this.vueInstance.i18nt("designer.hint.lastRowCannotBeDeleted")
1022
- );
1023
- return;
1024
- }
1025
-
1026
- //整行所有单元格行高不一致不可删除!!
1027
- let startRowspan = rowArray[rowIndex].cols[0].options.rowspan;
1028
- let unmatchedFlag = false;
1029
- for (let i = 1; i < rowArray[rowIndex].cols.length; i++) {
1030
- if (rowArray[rowIndex].cols[i].options.rowspan !== startRowspan) {
1031
- unmatchedFlag = true;
1032
- break;
1033
- }
1034
- }
1035
- if (unmatchedFlag) {
1036
- this.vueInstance.$message.info(
1037
- this.vueInstance.i18nt(
1038
- "designer.hint.rowspanNotConsistentForDeleteEntireRow"
1039
- )
1040
- );
1041
- return;
1042
- }
1043
-
1044
- rowArray.splice(rowIndex, startRowspan);
1045
-
1046
- this.emitHistoryChange();
1047
- },
1048
-
1049
- getContainerByType(typeName) {
1050
- let allWidgets = [
1051
- ...baseRefUtil.containers,
1052
- ...baseRefUtil.basicFields,
1053
- ...baseRefUtil.advancedFields,
1054
- ...baseRefUtil.customFields,
1055
- ...businessFields,
1056
- ];
1057
- let foundCon = null;
1058
- allWidgets.forEach((con) => {
1059
- if (!!con.category && !!con.type && con.type === typeName) {
1060
- foundCon = con;
1061
- }
1062
- });
1063
-
1064
- return foundCon;
1065
- },
1066
-
1067
- getFieldWidgetByType(typeName) {
1068
- let allWidgets = [
1069
- ...baseRefUtil.containers,
1070
- ...baseRefUtil.basicFields,
1071
- ...baseRefUtil.advancedFields,
1072
- ...baseRefUtil.customFields,
1073
- ...chartContainers,
1074
- ...chartWidgets,
1075
- ...businessFields,
1076
- ];
1077
- let foundWidget = null;
1078
- allWidgets.forEach((widget) => {
1079
- if (!!!widget.category && !!widget.type && widget.type === typeName) {
1080
- foundWidget = widget;
1081
- }
1082
- });
1083
-
1084
- return foundWidget;
1085
- },
1086
-
1087
- hasConfig(widget, configName) {
1088
- let originalWidget = null;
1089
- if (!!widget.category) {
1090
- originalWidget = this.getContainerByType(widget.type);
1091
- } else {
1092
- originalWidget = this.getFieldWidgetByType(widget.type);
1093
- }
1094
-
1095
- if (!originalWidget || !originalWidget.options) {
1096
- return false;
1097
- }
1098
-
1099
- return Object.keys(originalWidget.options).indexOf(configName) > -1;
1100
- },
1101
- /*upgradeWidgetConfig(oldWidget) {
1102
- let newWidget = null;
1103
- if (!!oldWidget.category) {
1104
- newWidget = this.getContainerByType(oldWidget.type);
1105
- } else {
1106
- newWidget = this.getFieldWidgetByType(oldWidget.type);
1107
- }
1108
-
1109
- if (!newWidget || !newWidget.options) {
1110
- return;
1111
- }
1112
-
1113
- Object.keys(newWidget.options).forEach(ck => {
1114
- if (!oldWidget.options.hasOwnProperty(ck)) {
1115
- oldWidget.options[ck] = baseRefUtil.deepClone(newWidget.options[ck]);
1116
- }
1117
- });
1118
- },*/
1119
- upgradeWidgetConfig(oldWidget) {
1120
- let newWidget = null;
1121
- if (!!oldWidget.category) {
1122
- newWidget = this.getContainerByType(oldWidget.type);
1123
- } else {
1124
- newWidget = this.getFieldWidgetByType(oldWidget.type);
1125
- }
1126
-
1127
- if (!newWidget || !newWidget.options) {
1128
- return;
1129
- }
1130
-
1131
- Object.keys(newWidget.options).forEach((ck) => {
1132
- if (!oldWidget.options.hasOwnProperty(ck)) {
1133
- let value = newWidget.options[ck];
1134
- let nullValue = Array.isArray(value) ? [] : null;
1135
- oldWidget.options[ck] = nullValue;
1136
- }
1137
- });
1138
- },
1139
-
1140
- upgradeFormConfig(oldFormConfig) {
1141
- Object.keys(this.formConfig).forEach((fc) => {
1142
- if (!oldFormConfig.hasOwnProperty(fc)) {
1143
- let value = this.formConfig[fc];
1144
- let nullValue = Array.isArray(value) ? [] : null;
1145
- oldFormConfig[fc] = baseRefUtil.deepClone(nullValue);
1146
- }
1147
- });
1148
- },
1149
-
1150
- cloneGridCol(widget, parentWidget) {
1151
- let newGridCol = baseRefUtil.deepClone(
1152
- this.getContainerByType("grid-col")
1153
- );
1154
- newGridCol.options.span = widget.options.span;
1155
- let tmpId = baseRefUtil.generateId();
1156
- newGridCol.id = "grid-col-" + tmpId;
1157
- newGridCol.options.name = "gridCol" + tmpId;
1158
-
1159
- parentWidget.cols.push(newGridCol);
1160
- },
1161
-
1162
- cloneContainer(containWidget) {
1163
- if (containWidget.type === "grid") {
1164
- let newGrid = baseRefUtil.deepClone(this.getContainerByType("grid"));
1165
- newGrid.id = newGrid.type + baseRefUtil.generateId();
1166
- newGrid.options.name = newGrid.id;
1167
- containWidget.cols.forEach((gridCol) => {
1168
- let newGridCol = baseRefUtil.deepClone(
1169
- this.getContainerByType("grid-col")
1170
- );
1171
- let tmpId = baseRefUtil.generateId();
1172
- newGridCol.id = "grid-col-" + tmpId;
1173
- newGridCol.options.name = "gridCol" + tmpId;
1174
- newGridCol.options.span = gridCol.options.span;
1175
- newGrid.cols.push(newGridCol);
1176
- });
1177
-
1178
- return newGrid;
1179
- } else if (containWidget.type === "table") {
1180
- let newTable = baseRefUtil.deepClone(
1181
- this.getContainerByType("table")
1182
- );
1183
- newTable.id = newTable.type + baseRefUtil.generateId();
1184
- newTable.options.name = newTable.id;
1185
- containWidget.rows.forEach((tRow) => {
1186
- let newRow = baseRefUtil.deepClone(tRow);
1187
- newRow.id = "table-row-" + baseRefUtil.generateId();
1188
- newRow.cols.forEach((col) => {
1189
- col.id = "table-cell-" + baseRefUtil.generateId();
1190
- col.options.name = col.id;
1191
- col.widgetList = []; //清空组件列表
1192
- });
1193
- newTable.rows.push(newRow);
1194
- });
1195
-
1196
- return newTable;
1197
- } else if (containWidget.type === "h5-table") {
1198
- let newTable = baseRefUtil.deepClone(
1199
- this.getContainerByType("h5-table")
1200
- );
1201
- newTable.id = newTable.type + baseRefUtil.generateId();
1202
- newTable.options.name = newTable.id;
1203
- containWidget.rows.forEach((tRow) => {
1204
- let newRow = baseRefUtil.deepClone(tRow);
1205
- newRow.id = "table-row-" + baseRefUtil.generateId();
1206
- newRow.cols.forEach((col) => {
1207
- col.id = "table-cell-" + baseRefUtil.generateId();
1208
- col.options.name = col.id;
1209
- col.widgetList = []; //清空组件列表
1210
- });
1211
- newTable.rows.push(newRow);
1212
- });
1213
-
1214
- return newTable;
1215
- } else {
1216
- //其他容器组件不支持clone操作
1217
- return null;
1218
- }
1219
- },
1220
-
1221
- moveUpWidget(parentList, indexOfParentList) {
1222
- if (!!parentList) {
1223
- if (indexOfParentList === 0) {
1224
- this.vueInstance.$message(
1225
- this.vueInstance.i18nt("designer.hint.moveUpFirstChildHint")
1226
- );
1227
- return;
1228
- }
1229
-
1230
- let tempWidget = parentList[indexOfParentList];
1231
- parentList.splice(indexOfParentList, 1);
1232
- parentList.splice(indexOfParentList - 1, 0, tempWidget);
1233
- }
1234
- },
1235
-
1236
- moveDownWidget(parentList, indexOfParentList) {
1237
- if (!!parentList) {
1238
- if (indexOfParentList === parentList.length - 1) {
1239
- this.vueInstance.$message(
1240
- this.vueInstance.i18nt("designer.hint.moveDownLastChildHint")
1241
- );
1242
- return;
1243
- }
1244
-
1245
- let tempWidget = parentList[indexOfParentList];
1246
- parentList.splice(indexOfParentList, 1);
1247
- parentList.splice(indexOfParentList + 1, 0, tempWidget);
1248
- }
1249
- },
1250
- copyNewFieldWidget(origin) {
1251
- let newWidget = baseRefUtil.deepClone(origin);
1252
- let sourceType = newWidget.type;
1253
- newWidget.type = newWidget.targetType || newWidget.type;
1254
- newWidget.sourceType = sourceType;
1255
- let tempId = baseRefUtil.generateId();
1256
- newWidget.id = newWidget.type.replace(/-/g, "") + tempId;
1257
- if (newWidget.hasOwnProperty("tableField")) {
1258
- newWidget.tableField = newWidget.id; //表字段
1259
- }
1260
-
1261
- // newWidget.options.name = newWidget.id;
1262
- // newWidget.options.label = newWidget.options.label || newWidget.type.toLowerCase();
1263
-
1264
- newWidget.nameReadonly
1265
- ? newWidget.options.label &&
1266
- newWidget.options.label.indexOf(".") > -1 &&
1267
- (newWidget.options.label = newWidget.options.label.substring(
1268
- newWidget.options.label.indexOf(".") + 1
1269
- ))
1270
- : ((newWidget.options.name = newWidget.id),
1271
- (newWidget.options.label =
1272
- newWidget.options.label || newWidget.type.toLowerCase()));
1273
- delete newWidget.displayName;
1274
- if (!newWidget.nameReadonly) {
1275
- newWidget.options.keyNameEnabled = true;
1276
- if (!newWidget.options.keyName)
1277
- newWidget.options.keyName = newWidget.id;
1278
- if (
1279
- newWidget.type === "vabUpload" ||
1280
- newWidget.type === "baseAttachment"
1281
- ) {
1282
- let keyNameSuffix = this.createKeyNameSuffix(newWidget.type);
1283
- // this.createKeyNameSuffix()
1284
- newWidget.options.keyName = this.createKeyName(
1285
- newWidget.type,
1286
- keyNameSuffix
1287
- );
1288
- newWidget.options.keyNameSuffix = keyNameSuffix;
1289
- }
1290
- }
1291
- if (newWidget.type === "dropdown") {
1292
- let dropdownItem1 = this.copyNewFieldWidget(
1293
- this.getFieldWidgetByType("dropdown-item")
1294
- );
1295
- dropdownItem1.options.label = "下拉按钮1";
1296
- let dropdownItem2 = this.copyNewFieldWidget(
1297
- this.getFieldWidgetByType("dropdown-item")
1298
- );
1299
- dropdownItem2.options.label = "下拉按钮2";
1300
- newWidget.widgetList.push(dropdownItem1);
1301
- newWidget.widgetList.push(dropdownItem2);
1302
- }
1303
- this.emitEvent("canvas-add-field", newWidget.options.name);
1304
- return newWidget;
1305
- },
1306
- createKeyName(type, suffix, options) {
1307
- let keyNameSuffix = suffix ? suffix : this.createKeyNameSuffix(type);
1308
- let keyNamePrefix = this.getKeyNamePrefix(type, options);
1309
- let keyName = null;
1310
- if (keyNamePrefix) {
1311
- keyName = keyNamePrefix + keyNameSuffix;
1312
- } else {
1313
- keyName = keyNameSuffix;
1314
- }
1315
- return keyName;
1316
- },
1317
- createKeyNameSuffix(type) {
1318
- let suffix = createUUID();
1319
- /*if (type === "vabUpload" || type === "baseAttachment") {
1320
- let formCode = vueInstance.reportTemplate.formCode;
1321
- suffix = formCode + "_" + suffix;
1322
- }*/
1323
- return suffix;
1324
- },
1325
- /* 开了「值存为URL」的附件字段存的是主表普通列(值是 URL 字符串),不再走
1326
- attachments_ 独立附件通道,keyName 不能带前缀——否则保存时会被
1327
- data-table-mixin attachments_ 提取逻辑当附件包发走,主表列存不到 */
1328
- getKeyNamePrefix(type, options) {
1329
- if (options && options.urlValueEnabled) {
1330
- return null;
1331
- }
1332
- return keyNamePrefixMap[type] ?? null;
1333
- },
1334
- getFormCodePrefix(type) {
1335
- let prefix = this.getKeyNamePrefix(type) || "";
1336
- let attachmentPrefix =
1337
- prefix + vueInstance.reportTemplate.formCode + "_";
1338
- return attachmentPrefix;
1339
- },
1340
- createAttachmentSuffix() {
1341
- let type = "vabUpload";
1342
- return this.createKeyNameSuffix(type);
1343
- },
1344
- getAttachmentPrefix() {
1345
- let type = "vabUpload";
1346
- return this.getKeyNamePrefix(type);
1347
- },
1348
- getAttachmentFormCodePrefix() {
1349
- let type = "vabUpload";
1350
- let attachmentPrefix = this.getFormCodePrefix(type);
1351
- return attachmentPrefix;
1352
- },
1353
- createAttachmentKeyName(suffix) {
1354
- let type = "vabUpload";
1355
- let keyName = this.createKeyName(type, suffix);
1356
- return keyName;
1357
- },
1358
- copyNewContainerWidget(origin) {
1359
- let newCon = baseRefUtil.deepClone(origin);
1360
- let sourceType = newCon.type;
1361
- newCon.type = newCon.targetType || newCon.type;
1362
- newCon.sourceType = sourceType;
1363
- newCon.id = newCon.type.replace(/-/g, "") + baseRefUtil.generateId();
1364
- newCon.options.name = newCon.id;
1365
- if ((newCon.options.keyNameEnabled = true)) {
1366
- newCon.options.keyName = newCon.id;
1367
- }
1368
- if (newCon.hasOwnProperty("tableField")) {
1369
- newCon.tableField = newCon.id; //表字段
1370
- }
1371
- if (newCon.type === "grid") {
1372
- let newCol = baseRefUtil.deepClone(
1373
- this.getContainerByType("grid-col")
1374
- );
1375
- let tmpId = baseRefUtil.generateId();
1376
- newCol.id = "grid-col-" + tmpId;
1377
- newCol.options.name = "gridCol" + tmpId;
1378
- newCon.cols.push(newCol);
1379
- //
1380
- newCol = baseRefUtil.deepClone(newCol);
1381
- tmpId = baseRefUtil.generateId();
1382
- newCol.id = "grid-col-" + tmpId;
1383
- newCol.options.name = "gridCol" + tmpId;
1384
- newCon.cols.push(newCol);
1385
- } else if (newCon.type === "table") {
1386
- let newRow = {
1387
- cols: [],
1388
- };
1389
- newRow.id = "table-row-" + baseRefUtil.generateId();
1390
- newRow.merged = false;
1391
- for (let i = 0; i < 4; i++) {
1392
- let newCell = baseRefUtil.deepClone(
1393
- this.getContainerByType("table-cell")
1394
- );
1395
- newCell.id = "table-cell-" + baseRefUtil.generateId();
1396
- newCell.options.name = newCell.id;
1397
- newCell.merged = false;
1398
- newCell.options.colspan = 1;
1399
- newCell.options.rowspan = 1;
1400
- newRow.cols.push(newCell);
1401
- }
1402
- newCon.rows.push(newRow);
1403
- } else if (newCon.type === "tab") {
1404
- let newTabPane = baseRefUtil.deepClone(
1405
- this.getContainerByType("tab-pane")
1406
- );
1407
- newTabPane.id = "tab-pane-" + baseRefUtil.generateId();
1408
- newTabPane.options.name = "tab1";
1409
- newTabPane.options.label = "tab 1";
1410
- newCon.tabs.push(newTabPane);
1411
- } else if (newCon.type === "data-table") {
1412
- let add_button = this.copyNewFieldWidget(
1413
- this.getFieldWidgetByType("add_button")
1414
- );
1415
- add_button.options.onClick =
1416
- "this.getWidgetRef('" +
1417
- newCon.options.name +
1418
- "').openEditDialog();";
1419
- newCon.buttons.push(add_button);
1420
- } else if (newCon.type === "detail" || newCon.type === "detail-plain") {
1421
- /* detail-plain 无标题栏,不预置标题栏按钮;其余 panes 结构与 detail 一致 */
1422
- if (newCon.type === "detail") {
1423
- let buttonCon1 = this.copyNewFieldWidget(
1424
- this.getFieldWidgetByType("reset_button")
1425
- );
1426
- // buttonCon1.options.label = "重置";
1427
-
1428
- let buttonCon2 = this.copyNewFieldWidget(
1429
- this.getFieldWidgetByType("save_button")
1430
- );
1431
- buttonCon2.options.label = "保存";
1432
-
1433
- newCon.widgetList.push(buttonCon1);
1434
- newCon.widgetList.push(buttonCon2);
1435
- }
1436
-
1437
- let newCol = baseRefUtil.deepClone(
1438
- this.getContainerByType("detail-pane")
1439
- );
1440
- let tmpId = baseRefUtil.generateId();
1441
- newCol.id = "detail-pane-" + tmpId;
1442
- newCol.options.name = "detailPane" + tmpId;
1443
- newCol.options.label = "隐藏信息";
1444
- newCol.options.hidden = true;
1445
-
1446
- let tableCon = this.copyNewContainerWidget(
1447
- this.getContainerByType("table")
1448
- );
1449
- newCol.widgetList.push(tableCon);
1450
- newCon.panes.push(newCol);
1451
-
1452
- newCol = baseRefUtil.deepClone(
1453
- this.getContainerByType("detail-pane")
1454
- );
1455
- tmpId = baseRefUtil.generateId();
1456
- newCol.id = "detail-pane-" + tmpId;
1457
- newCol.options.name = "detailPane" + tmpId;
1458
- newCol.options.label = "基础信息";
1459
-
1460
- tableCon = this.copyNewContainerWidget(
1461
- this.getContainerByType("table")
1462
- );
1463
- newCol.widgetList.push(tableCon);
1464
- newCon.panes.push(newCol);
1465
- //
1466
- newCol = baseRefUtil.deepClone(
1467
- this.getContainerByType("detail-pane")
1468
- );
1469
- tmpId = baseRefUtil.generateId();
1470
- newCol.id = "detail-pane-" + tmpId;
1471
- newCol.options.name = "detailPane" + tmpId;
1472
- newCol.options.label = "明细信息";
1473
- newCol.options.tableRef = tableCon.id;
1474
- let dataTableCon = this.copyNewContainerWidget(
1475
- this.getContainerByType("data-table")
1476
- );
1477
- newCol.widgetList.push(dataTableCon);
1478
- newCol.options.tableRef = dataTableCon.id;
1479
-
1480
- let buttonCon3 = this.copyNewFieldWidget(
1481
- this.getFieldWidgetByType("button")
1482
- );
1483
- buttonCon3.options.label = "新增";
1484
- buttonCon3.options.icon = "el-icon-search";
1485
- // buttonCon3.options.onClick = "this.getWidgetRef('" + dataTableCon.options.name + "').addTableData();"
1486
- buttonCon3.options.clickBindEvent = CLICK_BIND.ADD_TABLE_DATA;
1487
- Object.assign(buttonCon3.options.addTableDataConfig, {
1488
- tableRef: dataTableCon.options.name,
1489
- });
1490
-
1491
- newCol.buttonWidgetList.push(buttonCon3);
1492
- newCon.panes.push(newCol);
1493
-
1494
- newCol = baseRefUtil.deepClone(
1495
- this.getContainerByType("detail-pane")
1496
- );
1497
- tmpId = baseRefUtil.generateId();
1498
- newCol.id = "detail-pane-" + tmpId;
1499
- newCol.options.name = "detailPane" + tmpId;
1500
- newCol.options.label = "附件信息";
1501
- let vabUploadCon = this.copyNewFieldWidget(
1502
- this.getFieldWidgetByType("vabUpload")
1503
- ); //vabUpload
1504
- newCol.widgetList.push(vabUploadCon);
1505
- newCon.panes.push(newCol);
1506
-
1507
- /* 「详情模块(标签)」面板条目:type=detail-tabs + targetType=detail,落地后就是 detail,
1508
- 不是新的容器类型。与「详情模块」的区别是内容模块不直接挂在正文区,而是收进标签里,
1509
- 详见 docs/详情模块标签承载方案.md */
1510
- if (newCon.sourceType === "detail-tabs") {
1511
- // 上面已按 detail 的默认骨架建好一批内容模块,整体挪进第一个标签——
1512
- // 标签形态下正文区只放标签容器,不留散在标签外面的模块。
1513
- let presetPanes = newCon.panes.splice(0);
1514
-
1515
- // 标签内的模块由 detail-plain 承载:它自带一套独立锚点导航,
1516
- // 外层 baseTabs 探测不到标签内的模块(tab-item 不满足 getTabs 的两个条件)。
1517
- let plainCon = this.copyNewContainerWidget(
1518
- this.getContainerByType("detail-plain")
1519
- );
1520
- plainCon.panes = presetPanes; // 丢掉 detail-plain 自带的默认模块,用上面建好的这批
1521
- plainCon.options.hideNav = false; // schema 默认关导航,标签内要开
1522
-
1523
- let tabCon = this.copyNewContainerWidget(
1524
- this.getContainerByType("tab")
1525
- );
1526
- tabCon.tabs[0].widgetList.push(plainCon);
1527
-
1528
- // copyNewContainerWidget 只预置 1 个 tab-pane,只有一个标签页的标签栏看着像 bug,补第二个
1529
- let secondPane = baseRefUtil.deepClone(
1530
- this.getContainerByType("tab-pane")
1531
- );
1532
- secondPane.id = "tab-pane-" + baseRefUtil.generateId();
1533
- secondPane.options.name = "tab2";
1534
- secondPane.options.label = "tab 2";
1535
- tabCon.tabs.push(secondPane);
1536
-
1537
- newCon.panes.push(tabCon);
1538
- }
1539
- } else if (newCon.type === "table-column") {
1540
- newCon.options.label = "tableColumn";
1541
- } else if (newCon.type === "h5-card") {
1542
- let newCol = baseRefUtil.deepClone(
1543
- this.getContainerByType("h5-card-pane")
1544
- );
1545
- let tmpId = baseRefUtil.generateId();
1546
- newCol.id = "h5-card-pane-" + tmpId;
1547
- newCol.options.name = "h5CardPane" + tmpId;
1548
- newCol.options.label = "基本信息";
1549
- newCon.panes.push(newCol);
1550
- } else if (newCon.type === "detail-h5") {
1551
- // 一张 h5-card:基础信息 / 明细信息 / 附件信息
1552
- let newCard = this.copyNewContainerWidget(
1553
- this.getContainerByType("h5-card")
1554
- );
1555
- newCon.panes.push(newCard);
1556
-
1557
- // 基础信息:默认放 h5 表格(一行两列),对齐 PC 详情的「基础信息 + 表格」
1558
- let basicPane = newCard.panes[0];
1559
- if (basicPane) {
1560
- basicPane.options.label = "基础信息";
1561
- let h5Table = this.copyNewContainerWidget(
1562
- this.getContainerByType("h5-table")
1563
- );
1564
- basicPane.widgetList.push(h5Table);
1565
- }
1566
-
1567
- // 明细信息:H5 列表;只读阶段不预置新增/查看按钮(点行仍可进详情)
1568
- let newCardPane = this.copyNewContainerWidget(
1569
- this.getContainerByType("h5-card-pane")
1570
- );
1571
- newCardPane.options.label = "明细信息";
1572
- newCard.panes.push(newCardPane);
1573
-
1574
- let listH5 = this.copyNewContainerWidget(
1575
- this.getContainerByType("list-h5")
1576
- );
1577
- newCardPane.widgetList.push(listH5);
1578
-
1579
- // 附件信息
1580
- newCardPane = this.copyNewContainerWidget(
1581
- this.getContainerByType("h5-card-pane")
1582
- );
1583
- newCardPane.options.label = "附件信息";
1584
- newCard.panes.push(newCardPane);
1585
-
1586
- let vabUploadCon = this.copyNewFieldWidget(
1587
- this.getFieldWidgetByType("vabUpload")
1588
- );
1589
- newCardPane.widgetList.push(vabUploadCon);
1590
- } else if (newCon.type === "h5-table") {
1591
- /* 默认 4 行 × 2 列,对齐 H5「一行两个」的紧凑版式。
1592
- 不再预置 input:H5 面板已下架单行输入,空单元格由设计者拖入字段。 */
1593
- const h5TableCols = 2;
1594
- const h5TableRows = 4;
1595
- for (let i = 0; i < h5TableRows; i++) {
1596
- let newRow = {
1597
- cols: [],
1598
- };
1599
- newRow.id = "table-row-" + baseRefUtil.generateId();
1600
- newRow.merged = false;
1601
-
1602
- for (let j = 0; j < h5TableCols; j++) {
1603
- let newCell = baseRefUtil.deepClone(
1604
- this.getContainerByType("h5-table-cell")
1605
- );
1606
- newCell.id = "table-cell-" + baseRefUtil.generateId();
1607
- newCell.options.name = newCell.id;
1608
- newCell.merged = false;
1609
- newCell.options.colspan = 1;
1610
- newCell.options.rowspan = 1;
1611
- newRow.cols.push(newCell);
1612
- }
1613
-
1614
- newCon.rows.push(newRow);
1615
- }
1616
- } else if (newCon.type === "tree-pane") {
1617
- //初始化列表
1618
- let dataTableCon = this.copyNewContainerWidget(
1619
- this.getContainerByType("data-table")
1620
- );
1621
- dataTableCon.options.showPagination = true;
1622
- dataTableCon.options.showSearchArea = true;
1623
- dataTableCon.options.isQueryTable = true;
1624
- dataTableCon.options.tableHeight = "auto";
1625
- dataTableCon.options.accessReturnType = "2";
1626
-
1627
- newCon.widgetList.push(dataTableCon);
1628
-
1629
- let addButton = this.copyNewFieldWidget(
1630
- this.getFieldWidgetByType("add_button")
1631
- );
1632
- addButton.options.onClick =
1633
- "this.getWidgetRef('" +
1634
- dataTableCon.options.name +
1635
- "').openEditDialog();";
1636
- dataTableCon.buttons.push(addButton);
1637
-
1638
- let tableExportButton = this.copyNewFieldWidget(
1639
- this.getFieldWidgetByType("table-export-button")
1640
- );
1641
- tableExportButton.options.tableExportParam =
1642
- "return { title: '导出', targetRef: '" +
1643
- dataTableCon.options.name +
1644
- "'}";
1645
- dataTableCon.buttons.push(tableExportButton);
1646
-
1647
- // 两个查询条件的值由树节点点击注入,勾上「固定查询条件」后
1648
- // 刷新、查询条件设置的还原/确定都不会把它清掉
1649
- let searchInput = this.copyNewFieldWidget(
1650
- this.getFieldWidgetByType("input")
1651
- );
1652
- searchInput.options.disabled = true;
1653
- searchInput.options.fixedQuery = true;
1654
- searchInput.options.label = newCon.options.treeLabel;
1655
- dataTableCon.widgetList.push(searchInput);
1656
-
1657
- let searchIdInput = this.copyNewFieldWidget(
1658
- this.getFieldWidgetByType("input")
1659
- );
1660
- searchIdInput.options.disabled = true;
1661
- searchIdInput.options.hidden = true;
1662
- searchIdInput.options.fixedQuery = true;
1663
- searchIdInput.options.label = `隐藏${newCon.options.treeLabel}ID`;
1664
- dataTableCon.widgetList.push(searchIdInput);
1665
-
1666
- // 存量表单没有 fixedQuery 开关,仍靠 ignoreFields 兜底刷新按钮;
1667
- // 新建的表单两条通道并存(取并集),不冲突
1668
- dataTableCon.options.onResetTable = `this.resetEvent({\n ignoreFields:['${searchInput.options.name}', '${searchIdInput.options.name}']\n});`;
1669
-
1670
- //初始化树
1671
- let treeCon = this.copyNewContainerWidget(
1672
- this.getContainerByType("tree")
1673
- );
1674
- treeCon.options.onNodeClick = `this.getWidgetRef('${searchInput.options.name}').setValue(data.label);\nthis.getWidgetRef('${searchIdInput.options.name}').setValue(data.id);\nthis.getWidgetRef('${dataTableCon.options.name}').searchEvent();`;
1675
-
1676
- newCon.options.onTreeLabelClick = `this.getWidgetRef('${treeCon.options.name}').setCurrentKey();\nthis.getWidgetRef('${searchInput.options.name}').setValue(null);\nthis.getWidgetRef('${searchIdInput.options.name}').setValue(null);\nthis.getWidgetRef('${dataTableCon.options.name}').searchEvent();`;
1677
- newCon.leftWidgetList.push(treeCon);
1678
- }
1679
- //newCon.options.customClass = []
1680
-
1681
- delete newCon.displayName;
1682
- return newCon;
1683
- },
1684
-
1685
- addContainerByDbClick(container) {
1686
- let newCon = this.copyNewContainerWidget(container);
1687
- this.widgetList.push(newCon);
1688
- this.setSelected(newCon);
1689
- },
1690
-
1691
- addFieldByDbClick(widget) {
1692
- let newWidget = this.copyNewFieldWidget(widget);
1693
- if (!!this.selectedWidget && this.selectedWidget.type === "tab") {
1694
- //获取当前激活的tabPane
1695
- let activeTab = this.selectedWidget.tabs[0];
1696
- this.selectedWidget.tabs.forEach((tabPane) => {
1697
- if (!!tabPane.options.active) {
1698
- activeTab = tabPane;
1699
- }
1700
- });
1701
-
1702
- !!activeTab && activeTab.widgetList.push(newWidget);
1703
- } else if (!!this.selectedWidget && !!this.selectedWidget.widgetList) {
1704
- this.selectedWidget.widgetList.push(newWidget);
1705
- } else {
1706
- this.widgetList.push(newWidget);
1707
- }
1708
-
1709
- this.setSelected(newWidget);
1710
- this.emitEvent("canvas-add-field", newWidget.options.name),
1711
- this.emitHistoryChange();
1712
- },
1713
- /**
1714
- * 删除详情容器下的一个 pane。
1715
- * @param gridWidget 详情容器(detail / detail-plain)
1716
- * @param paneOrIdx pane 的 widget 引用,或它在 panes 中的下标。
1717
- * detail 的属性面板按 type 做了显隐,下标不再可靠,故走引用;
1718
- * detail-plain 的属性面板仍传下标,这里一并兼容。
1719
- */
1720
- deletePaneOfDetail(gridWidget, paneOrIdx) {
1721
- if (!gridWidget || !gridWidget.panes) return;
1722
- let isIdx = typeof paneOrIdx === "number";
1723
- let colIdx = isIdx ? paneOrIdx : gridWidget.panes.indexOf(paneOrIdx);
1724
- if (colIdx < 0) return;
1725
- gridWidget.panes.splice(colIdx, 1);
1726
- },
1727
- cloneDetailPane(widget, parentWidget) {
1728
- let newGridCol = baseRefUtil.deepClone(
1729
- this.getContainerByType("detail-pane")
1730
- );
1731
- let tmpId = baseRefUtil.generateId();
1732
- newGridCol.id = "detail-pane-" + tmpId;
1733
- newGridCol.options.name = "detailPane" + tmpId;
1734
- newGridCol.options.label = widget.options.label;
1735
- parentWidget.panes.push(newGridCol);
1736
- },
1737
- cloneH5CardPanePane(widget, parentWidget) {
1738
- let newGridCol = baseRefUtil.deepClone(
1739
- this.getContainerByType("h5-card-pane")
1740
- );
1741
- let tmpId = baseRefUtil.generateId();
1742
- newGridCol.id = "h5-card-pane-" + tmpId;
1743
- newGridCol.options.name = "h5CardPane" + tmpId;
1744
- newGridCol.options.label = widget.options.label;
1745
- parentWidget.panes.push(newGridCol);
1746
- },
1747
-
1748
- addNewPaneOfDetail(gridWidget) {
1749
- const cols = gridWidget.panes;
1750
- let newGridCol = baseRefUtil.deepClone(
1751
- this.getContainerByType("detail-pane")
1752
- );
1753
- let tmpId = baseRefUtil.generateId();
1754
- newGridCol.id = "detail-pane-" + tmpId;
1755
- newGridCol.options.name = "detailPane" + tmpId;
1756
- newGridCol.options.label = "detailPane" + tmpId;
1757
- // 默认添加一个栅格控件到新 pane widgetList 中,含3列平均分布
1758
- let defaultGrid = baseRefUtil.deepClone(
1759
- this.getContainerByType("grid")
1760
- );
1761
- defaultGrid.id = "grid-" + baseRefUtil.generateId();
1762
- // 添加3列,每列 span=8(24栏栅格均分)
1763
- for (let i = 0; i < 3; i++) {
1764
- let col = baseRefUtil.deepClone(
1765
- this.getContainerByType("grid-col")
1766
- );
1767
- col.id = "grid-col-" + baseRefUtil.generateId();
1768
- col.options.span = 8;
1769
- defaultGrid.cols.push(col);
1770
- }
1771
- newGridCol.widgetList.push(defaultGrid);
1772
- gridWidget.panes.push(newGridCol);
1773
- },
1774
-
1775
- deleteColOfGrid(gridWidget, colIdx) {
1776
- if (!!gridWidget && !!gridWidget.cols) {
1777
- gridWidget.cols.splice(colIdx, 1);
1778
- }
1779
- },
1780
-
1781
- addNewColOfGrid(gridWidget) {
1782
- const cols = gridWidget.cols;
1783
- let newGridCol = baseRefUtil.deepClone(
1784
- this.getContainerByType("grid-col")
1785
- );
1786
- let tmpId = baseRefUtil.generateId();
1787
- newGridCol.id = "grid-col-" + tmpId;
1788
- newGridCol.options.name = "gridCol" + tmpId;
1789
- if (!!cols && cols.length > 0) {
1790
- let spanSum = 0;
1791
- cols.forEach((col) => {
1792
- spanSum += col.options.span;
1793
- });
1794
-
1795
- if (spanSum >= 24) {
1796
- //this.$message.info('列栅格之和超出24')
1797
- console.log("列栅格之和超出24");
1798
- gridWidget.cols.push(newGridCol);
1799
- } else {
1800
- newGridCol.options.span = 24 - spanSum > 12 ? 12 : 24 - spanSum;
1801
- gridWidget.cols.push(newGridCol);
1802
- }
1803
- } else {
1804
- gridWidget.cols = [newGridCol];
1805
- }
1806
- },
1807
-
1808
- addTabPaneOfTabs(tabsWidget) {
1809
- const tabPanes = tabsWidget.tabs;
1810
- let newTabPane = baseRefUtil.deepClone(
1811
- this.getContainerByType("tab-pane")
1812
- );
1813
- newTabPane.id = "tab-pane-" + baseRefUtil.generateId();
1814
- newTabPane.options.name = newTabPane.id;
1815
- newTabPane.options.label = "tab " + (tabPanes.length + 1);
1816
- tabPanes.push(newTabPane);
1817
- },
1818
-
1819
- deleteTabPaneOfTabs(tabsWidget, tpIdx) {
1820
- tabsWidget.tabs.splice(tpIdx, 1);
1821
- },
1822
-
1823
- addDropdownItem(tabsWidget) {
1824
- const tabPanes = tabsWidget.widgetList;
1825
- let newTabPane = baseRefUtil.deepClone(
1826
- this.getFieldWidgetByType("dropdown-item")
1827
- );
1828
- newTabPane.id = "dropdown-item-" + baseRefUtil.generateId();
1829
- newTabPane.options.name = newTabPane.id;
1830
- newTabPane.options.label = "dropdown-item " + (tabPanes.length + 1);
1831
- tabPanes.push(newTabPane);
1832
- },
1833
-
1834
- deleteDropdownItem(tabsWidget, tpIdx) {
1835
- tabsWidget.widgetList.splice(tpIdx, 1);
1836
- },
1837
-
1838
- emitEvent(evtName, evtData) {
1839
- //用于兄弟组件发射事件
1840
- this.vueInstance.$emit(evtName, evtData);
1841
- },
1842
-
1843
- handleEvent(evtName, callback) {
1844
- //用于兄弟组件接收事件
1845
- this.vueInstance.$on(evtName, (data) => callback(data));
1846
- },
1847
-
1848
- setCssClassList(cssClassList) {
1849
- this.cssClassList = cssClassList;
1850
- },
1851
-
1852
- getCssClassList() {
1853
- return this.cssClassList;
1854
- },
1855
-
1856
- registerFormWidget(formWidget) {
1857
- this.formWidget = formWidget;
1858
- },
1859
-
1860
- initHistoryData() {
1861
- this.loadFormContentFromStorage();
1862
- this.historyData.index++;
1863
- this.historyData.steps[this.historyData.index] = {
1864
- widgetList: baseRefUtil.deepClone(this.widgetList),
1865
- formConfig: baseRefUtil.deepClone(this.formConfig),
1866
- };
1867
- },
1868
-
1869
- emitHistoryChange() {
1870
- //console.log('------------', 'Form history changed!')
1871
-
1872
- if (this.historyData.index === this.historyData.maxStep - 1) {
1873
- this.historyData.steps.shift();
1874
- } else {
1875
- this.historyData.index++;
1876
- }
1877
-
1878
- this.historyData.steps[this.historyData.index] = {
1879
- widgetList: baseRefUtil.deepClone(this.widgetList),
1880
- formConfig: baseRefUtil.deepClone(this.formConfig),
1881
- };
1882
-
1883
- this.saveFormContentToStorage();
1884
-
1885
- if (this.historyData.index < this.historyData.steps.length - 1) {
1886
- this.historyData.steps = this.historyData.steps.slice(
1887
- 0,
1888
- this.historyData.index + 1
1889
- );
1890
- }
1891
-
1892
- //console.log('history', this.historyData.index)
1893
- },
1894
-
1895
- saveCurrentHistoryStep() {
1896
- this.historyData.steps[this.historyData.index] = baseRefUtil.deepClone({
1897
- widgetList: this.widgetList,
1898
- formConfig: this.formConfig,
1899
- });
1900
-
1901
- this.saveFormContentToStorage();
1902
- },
1903
-
1904
- undoHistoryStep() {
1905
- if (this.historyData.index !== 0) {
1906
- this.historyData.index--;
1907
- }
1908
- //console.log('undo', this.historyData.index)
1909
-
1910
- this.widgetList = baseRefUtil.deepClone(
1911
- this.historyData.steps[this.historyData.index].widgetList
1912
- );
1913
- this.formConfig = baseRefUtil.deepClone(
1914
- this.historyData.steps[this.historyData.index].formConfig
1915
- );
1916
- },
1917
-
1918
- redoHistoryStep() {
1919
- if (this.historyData.index !== this.historyData.steps.length - 1) {
1920
- this.historyData.index++;
1921
- }
1922
- //console.log('redo', this.historyData.index)
1923
-
1924
- this.widgetList = baseRefUtil.deepClone(
1925
- this.historyData.steps[this.historyData.index].widgetList
1926
- );
1927
- this.formConfig = baseRefUtil.deepClone(
1928
- this.historyData.steps[this.historyData.index].formConfig
1929
- );
1930
- },
1931
-
1932
- undoEnabled() {
1933
- return this.historyData.index > 0 && this.historyData.steps.length > 0;
1934
- },
1935
-
1936
- redoEnabled() {
1937
- return this.historyData.index < this.historyData.steps.length - 1;
1938
- },
1939
-
1940
- saveFormContentToStorage() {
1941
- window.localStorage.setItem(
1942
- "widget__list__backup",
1943
- JSON.stringify(this.widgetList)
1944
- );
1945
- window.localStorage.setItem(
1946
- "form__config__backup",
1947
- JSON.stringify(this.formConfig)
1948
- );
1949
- },
1950
-
1951
- loadFormContentFromStorage() {
1952
- let widgetListBackup = window.localStorage.getItem(
1953
- "widget__list__backup"
1954
- );
1955
- if (!!widgetListBackup) {
1956
- this.widgetList = JSON.parse(widgetListBackup);
1957
- }
1958
-
1959
- let formConfigBackup = window.localStorage.getItem(
1960
- "form__config__backup"
1961
- );
1962
- if (!!formConfigBackup) {
1963
- //this.formConfig = JSON.parse(formConfigBackup)
1964
- baseRefUtil.overwriteObj(
1965
- this.formConfig,
1966
- JSON.parse(formConfigBackup)
1967
- ); /* 用=赋值,会导致inject依赖注入的formConfig属性变成非响应式 */
1968
- }
1969
- },
1970
- getColumnWidget(row, isEdit) {
1971
- //获取
1972
- let formatS = isEdit ? row.editFormatS : row.formatS;
1973
- let type = columnFormatMap[formatS];
1974
- if (!type) return null;
1975
- if (isEdit) {
1976
- if (row.editWidget) {
1977
- return row.editWidget;
1978
- }
1979
- if (row.editColumnOption) {
1980
- let fieldWidget = this.copyNewFieldWidget(
1981
- this.getFieldWidgetByType(type)
1982
- );
1983
- fieldWidget.options = row.editColumnOption;
1984
- return fieldWidget;
1985
- }
1986
- } else {
1987
- if (row.widget) {
1988
- return row.widget;
1989
- }
1990
- if (row.columnOption) {
1991
- let fieldWidget = this.copyNewFieldWidget(
1992
- this.getFieldWidgetByType(type)
1993
- );
1994
- fieldWidget.options = row.columnOption;
1995
- return fieldWidget;
1996
- }
1997
- }
1998
- return this.createColumnWidget(row, isEdit);
1999
- },
2000
- getIsFileWidget(type) {
2001
- return type === "vabUpload" || type === "baseAttachment";
2002
- },
2003
- createColumnWidget(row, isEdit) {
2004
- let formatS = isEdit ? row.editFormatS : row.formatS;
2005
- let type = columnFormatMap[formatS];
2006
- if (!type) return null;
2007
-
2008
- let columnSelectedWidget = null;
2009
- if (type) {
2010
- columnSelectedWidget = this.copyNewFieldWidget(
2011
- this.getFieldWidgetByType(type)
2012
- );
2013
-
2014
- if (columnSelectedWidget.options.hasOwnProperty("required")) {
2015
- columnSelectedWidget.options.required = row.required || false;
2016
- }
2017
-
2018
- if ("editDelete" === formatS) {
2019
- columnSelectedWidget.options.prefixIcon = "el-icon-delete";
2020
- columnSelectedWidget.options.label = "删除";
2021
- columnSelectedWidget.options.labelHidden = true;
2022
- columnSelectedWidget.options.hiddenByWf = true;
2023
- columnSelectedWidget.options.onClick =
2024
- "let tableParam = this.tableParam;\nlet tableRef = this.getWidgetRef(this.parentWidget.options.name);\ntableRef.deleteRow(tableParam.row,tableParam.rowIndex);";
2025
- } else if ("editButton" === formatS) {
2026
- columnSelectedWidget.options.prefixIcon = "el-icon-edit";
2027
- columnSelectedWidget.options.label = "查看";
2028
- columnSelectedWidget.options.labelHidden = true;
2029
- columnSelectedWidget.options.onClick =
2030
- "let tableParam = this.tableParam;\nlet tableRef = this.getWidgetRef(this.parentWidget.options.name);\ntableRef.openEditDialog(tableParam.row)";
2031
- } else if ("addSiblingEditRow" === formatS) {
2032
- columnSelectedWidget.options.prefixIcon = "el-icon-plus";
2033
- columnSelectedWidget.options.label = "新增兄弟节点";
2034
- columnSelectedWidget.options.labelHidden = false;
2035
- columnSelectedWidget.options.onClick =
2036
- "let tableParam = this.tableParam;\nthis.getParentTarget().addSiblingTreeRow(null,tableParam);";
2037
- } else if ("addChildTreeRow" === formatS) {
2038
- columnSelectedWidget.options.prefixIcon = "el-icon-plus";
2039
- columnSelectedWidget.options.label = "新增子节点";
2040
- columnSelectedWidget.options.labelHidden = false;
2041
- columnSelectedWidget.options.onClick =
2042
- "let tableParam = this.tableParam;\nthis.getParentTarget().addChildTreeRow(null,tableParam);";
2043
- } else if ("moveUpRow" === formatS) {
2044
- columnSelectedWidget.options.label = "↑上移";
2045
- columnSelectedWidget.options.labelHidden = false;
2046
- columnSelectedWidget.options.onClick =
2047
- "let tableParam = this.tableParam;\nthis.getParentTarget().moveUpRow(tableParam);";
2048
- } else if ("moveDownRow" === formatS) {
2049
- columnSelectedWidget.options.label = "↓下移";
2050
- columnSelectedWidget.options.labelHidden = false;
2051
- columnSelectedWidget.options.onClick =
2052
- "let tableParam = this.tableParam;\nthis.getParentTarget().moveDownRow(tableParam);";
2053
- } else if ("removeTreeRow" === formatS) {
2054
- columnSelectedWidget.options.prefixIcon = "el-icon-delete";
2055
- columnSelectedWidget.options.label = "删除";
2056
- columnSelectedWidget.options.labelHidden = true;
2057
- columnSelectedWidget.options.onClick =
2058
- "let tableParam = this.tableParam;\nthis.getParentTarget().removeTreeRow(tableParam);";
2059
- }
2060
-
2061
- if (columnSelectedWidget.options.hasOwnProperty("keyName")) {
2062
- if (!this.getIsFileWidget(type)) {
2063
- columnSelectedWidget.options.keyName = row.prop;
2064
- }
2065
-
2066
- columnSelectedWidget.options.keyNameEnabled = true;
2067
- } else {
2068
- columnSelectedWidget.options.name = row.prop;
2069
- }
2070
-
2071
- if (type === "dropdown") {
2072
- columnSelectedWidget.options.dropdownType = "link";
2073
- } else if (type !== "button" && type !== "a-link") {
2074
- columnSelectedWidget.options.label = row.label;
2075
- columnSelectedWidget.options.labelHidden = true;
2076
- }
2077
- }
2078
- return columnSelectedWidget;
2079
- },
2080
- };
2081
- };
2082
- })();
2083
-
2084
- export const createDesigner = createDesigner0;
1
+ /**
2
+ * author: vformAdmin
3
+ * email: vdpadmin@163.com
4
+ * website: https://www.vform666.com
5
+ * date: 2021.08.18
6
+ * remark: 如果要分发VForm源码,需在本文件顶部保留此文件头信息!!
7
+ */
8
+
9
+ import {
10
+ deepClone,
11
+ generateId,
12
+ getDefaultFormConfig,
13
+ overwriteObj,
14
+ createUUID,
15
+ columnFormatMap,
16
+ } from "../../../components/xform/utils/util";
17
+ import { CLICK_BIND } from "./setting-panel/property-editor/field-button/clickBindActions";
18
+ import {
19
+ containers,
20
+ advancedFields,
21
+ basicFields,
22
+ customFields,
23
+ businessFields,
24
+ } from "../../../components/xform/form-designer/widget-panel/widgetsConfig.js";
25
+ import { VARIANT_FORM_VERSION } from "../../../components/xform/utils/config";
26
+ import { keyNamePrefixMap } from "../../../components/xform/form-designer/widget-panel/widgetsConfig";
27
+
28
+ let createDesigner0;
29
+ const baseRefUtil = {
30
+ deepClone,
31
+ generateId,
32
+ getDefaultFormConfig,
33
+ overwriteObj,
34
+ containers,
35
+ advancedFields,
36
+ basicFields,
37
+ customFields,
38
+ VARIANT_FORM_VERSION,
39
+ };
40
+
41
+ let chartContainers = [],
42
+ chartWidgets = [];
43
+
44
+ (function () {
45
+ createDesigner0 = function (vueInstance) {
46
+ let defaultFormConfig = baseRefUtil.deepClone(
47
+ baseRefUtil.getDefaultFormConfig()
48
+ );
49
+
50
+ return {
51
+ widgetList: [],
52
+ formConfig: {
53
+ cssCode: "",
54
+ gridConfig: {
55
+ accessReturnType: 1,
56
+ isLoadDataByAccess: false,
57
+ },
58
+ scriptList: [],
59
+ formType: 0,
60
+ getConfig: {
61
+ accessType: "1",
62
+ accessUrl: null,
63
+ accessParam: null,
64
+ accessCallback: null,
65
+ scriptName: null,
66
+ scriptCode: null,
67
+ },
68
+ saveConfig: {
69
+ accessType: "1",
70
+ accessUrl: null,
71
+ accessParam: null,
72
+ accessCallback: null,
73
+ scriptName: null,
74
+ scriptCode: null,
75
+ },
76
+ editFormCode: null,
77
+ editFormName: null,
78
+ searchDialogNameField: null,
79
+ searchDialogUniqueField: null,
80
+ entity: null,
81
+ wfEnabled: false,
82
+ isLoadEntity: false,
83
+ formScriptCode: "getOne",
84
+ formScriptParam: null,
85
+ formScriptSuccess: null,
86
+ saveScriptCode: "saveUpdate",
87
+ wfConfig: null,
88
+ wfStartBindSave: false,
89
+ wfStartConfirmText: null,
90
+ wfAgreenBindSave: false,
91
+ wfAgreeConfigData: [],
92
+ wfConfigDataEnabled: false,
93
+ wfConfigData: [],
94
+ multiTabEnabled: false,
95
+ multiTabLabelField: null,
96
+ addTabEnabled: false, // 新增打开独立页签(不走「常规」页签)
97
+ submitBehavior: "refreshCurrent", // 提交后行为: refreshCurrent(默认,留在详情页) | closeToList
98
+ billNavEnabled: false, // 详情页签显示「上一单/下一单」翻单按钮
99
+ addFormCode: null,
100
+ addFormName: null,
101
+ wfTheme: null,
102
+ otherTabEnabled: false,
103
+ otherTabList: [],
104
+ hideNormalTab: false,
105
+ customListTabLabel: null,
106
+ globalConfig: null,
107
+ // 表单级动态字段规则
108
+ dynamicFieldEnabled: false,
109
+ dynamicFieldRunMode: "auto",
110
+ dynamicFieldAllowValue: false,
111
+ dynamicFieldSourceType: "local",
112
+ dynamicFieldRules: [],
113
+ dynamicFieldScriptCode: null,
114
+ dynamicFieldScriptParam: null,
115
+ dynamicFieldTriggerFields: [],
116
+ },
117
+ dataSources: [], //数据源
118
+
119
+ selectedId: null,
120
+ selectedWidget: null,
121
+ selectedWidgetName: null, //选中组件名称(唯一)
122
+ vueInstance: vueInstance,
123
+
124
+ formWidget: null, //表单设计容器
125
+
126
+ cssClassList: [], //自定义样式列表
127
+
128
+ historyData: {
129
+ index: -1, //index: 0,
130
+ maxStep: 20,
131
+ steps: [],
132
+ },
133
+
134
+ initDesigner(resetFormJson) {
135
+ this.widgetList = [];
136
+ this.formConfig = baseRefUtil.deepClone(defaultFormConfig);
137
+ this.dataSources = [];
138
+
139
+ //输出版本信息和语雀链接
140
+ /* console.info(`%cVariantForm %cVer${baseRefUtil.VARIANT_FORM_VERSION} %chttps://www.yuque.com/visualdev/vform`,
141
+ "color:#409EFF;font-size: 22px;font-weight:bolder",
142
+ "color:#999;font-size: 12px",
143
+ "color:#333"
144
+ ); */
145
+
146
+ /*if (!resetFormJson) {
147
+ this.initHistoryData();
148
+ }*/
149
+ },
150
+
151
+ clearDesigner(skipHistoryChange) {
152
+ let emptyWidgetListFlag = this.widgetList.length === 0;
153
+ /* 版式是"当前在设计哪一端",不是表单内容的一部分。defaultFormConfig 里没有
154
+ layoutType,overwriteObj 之后 getLayoutType() 会退回 "PC" —— 在 H5 模板里
155
+ 点一下「清空」,左侧面板就跳回 PC 组件列表了。先存后还。 */
156
+ let keepLayoutType = this.getLayoutType();
157
+ this.widgetList = [];
158
+ this.selectedId = null;
159
+ this.selectedWidgetName = null;
160
+ this.selectedWidget = {}; //this.selectedWidget = null
161
+ baseRefUtil.overwriteObj(this.formConfig, defaultFormConfig); //
162
+ this.formConfig.gridConfig = defaultFormConfig.gridConfig;
163
+ this.formConfig.layoutType = keepLayoutType;
164
+
165
+ if (!!skipHistoryChange) {
166
+ //什么也不做!!
167
+ } else if (!emptyWidgetListFlag) {
168
+ this.emitHistoryChange();
169
+ } else {
170
+ this.saveCurrentHistoryStep();
171
+ }
172
+ },
173
+
174
+ loadPresetCssCode(preCssCode) {
175
+ if (this.formConfig.cssCode === "" && !!preCssCode) {
176
+ this.formConfig.cssCode = preCssCode;
177
+ }
178
+ },
179
+
180
+ getLayoutType() {
181
+ return this.formConfig.layoutType || "PC";
182
+ },
183
+
184
+ changeLayoutType(newType) {
185
+ this.formConfig.layoutType = newType;
186
+ },
187
+
188
+ getImportTemplate() {
189
+ return {
190
+ widgetList: [],
191
+ // formConfig: baseRefUtil.deepClone(this.formConfig)
192
+ formConfig: baseRefUtil.deepClone(defaultFormConfig),
193
+ };
194
+ },
195
+
196
+ handleImportJson(formJson) {
197
+ let formConfig = formJson.formConfig;
198
+ if (formConfig.formCode === vueInstance?.reportTemplate?.formCode) {
199
+ return;
200
+ }
201
+ let widgetArr = formJson.widgetList;
202
+ let itemFieldMap = {
203
+ grid: "cols",
204
+ table: "rows",
205
+ "table-cell": "widgetList",
206
+ "h5-table": "rows",
207
+ "h5-table-cell": "widgetList",
208
+ tab: "tabs",
209
+ "tab-pane": "widgetList",
210
+ "grid-col": "widgetList",
211
+ "vf-box": "widgetList",
212
+ card: "widgetList",
213
+ detail: "panes",
214
+ "detail-plain": "panes",
215
+ "detail-pane": "widgetList",
216
+ "detail-h5": "panes",
217
+ "h5-card": "panes",
218
+ "h5-card-pane": "widgetList",
219
+ };
220
+ let loopDo = (widgetList) => {
221
+ if (!widgetList) return;
222
+ widgetList.forEach((widget) => {
223
+ if (widget.type === "data-table" || widget.type === "list-h5") {
224
+ let vailColumns = widget.options.tableColumns.filter(
225
+ (item) => item.prop && item.label
226
+ );
227
+ vailColumns.forEach((item) => {
228
+ if (item.formatS === "editAttachment") {
229
+ let prop = item.prop;
230
+ let columnOption = item.columnOption;
231
+ let editColumnOption = item.editColumnOption;
232
+
233
+ let suffix = this.createAttachmentSuffix();
234
+ let keyName = this.createAttachmentKeyName(suffix);
235
+ if (columnOption) {
236
+ columnOption.keyName = keyName;
237
+ columnOption.keyNameSuffix = suffix;
238
+ }
239
+ if (editColumnOption) {
240
+ editColumnOption.keyName = keyName;
241
+ editColumnOption.keyNameSuffix = suffix;
242
+ }
243
+ item.prop = keyName;
244
+ }
245
+ });
246
+ } else if (
247
+ widget.type === "vabUpload" ||
248
+ widget.type === "baseAttachment"
249
+ ) {
250
+ let suffix = this.createAttachmentSuffix();
251
+ let keyName = this.createAttachmentKeyName(suffix);
252
+ widget.options.keyName = keyName;
253
+ widget.options.keyNameSuffix = suffix;
254
+ } else {
255
+ if (widget.category === "container") {
256
+ let itemField = itemFieldMap[widget.type];
257
+ if (itemField) {
258
+ if ("table" === widget.type) {
259
+ widget[itemField].forEach((item) => {
260
+ loopDo(item.cols);
261
+ });
262
+ } else if ("h5-table" === widget.type) {
263
+ widget[itemField].forEach((item) => {
264
+ loopDo(item.cols);
265
+ });
266
+ } else {
267
+ loopDo(widget[itemField]);
268
+ }
269
+ }
270
+ }
271
+ }
272
+ });
273
+ };
274
+ loopDo(widgetArr);
275
+ },
276
+ loadFormJson(formJson) {
277
+ let modifiedFlag = false;
278
+
279
+ if (!!formJson && !!formJson.widgetList) {
280
+ this.widgetList = formJson.widgetList;
281
+ modifiedFlag = true;
282
+ }
283
+ if (!!formJson && !!formJson.formConfig) {
284
+ //this.formConfig = importObj.formConfig
285
+ baseRefUtil.overwriteObj(
286
+ this.formConfig,
287
+ formJson.formConfig
288
+ ); /* 用=赋值,会导致inject依赖注入的formConfig属性变成非响应式 */
289
+ modifiedFlag = true;
290
+ }
291
+
292
+ if (modifiedFlag) {
293
+ this.emitEvent("form-json-imported", []); // 通知其他组件
294
+ }
295
+ this.setSelected();
296
+ return modifiedFlag;
297
+ },
298
+ handleSelectedWidget(selected) {
299
+ //处理历史未定义的属性
300
+ if (selected.formItemFlag || selected.type === "data-table") {
301
+ if (selected.options.submitFlag === void 0) {
302
+ // selected.options.submitFlag = true;
303
+ this.vueInstance.$set(selected.options, "submitFlag", true);
304
+ }
305
+ }
306
+ this.handleKeyNameSuffix(selected);
307
+ },
308
+ handleKeyNameSuffix(selected) {
309
+ if (!selected) return;
310
+ let optionModel = selected.options;
311
+ let prefix = this.getKeyNamePrefix(selected.type, optionModel);
312
+ if (
313
+ optionModel.keyNameEnabled &&
314
+ !!prefix &&
315
+ !optionModel.keyNameSuffix
316
+ ) {
317
+ let keyName = optionModel.keyName;
318
+ if (keyName.startsWith(prefix)) {
319
+ this.vueInstance.$set(
320
+ optionModel,
321
+ "keyNameSuffix",
322
+ keyName.substring(prefix.length)
323
+ );
324
+ }
325
+ }
326
+ },
327
+ setSelected(selected) {
328
+ if (!selected) {
329
+ this.clearSelected();
330
+ return;
331
+ }
332
+
333
+ //处理历史未定义的属性
334
+ this.handleSelectedWidget(selected);
335
+
336
+ this.selectedWidget = selected;
337
+ if (!!selected.id) {
338
+ this.selectedId = selected.id;
339
+ this.selectedWidgetName = selected.options.name;
340
+ if (!selected.category) {
341
+ this.emitEvent("canvas-select-field", selected.options.name);
342
+ } else {
343
+ this.emitEvent("canvas-select-container", selected.options.name);
344
+ }
345
+ }
346
+ },
347
+
348
+ updateSelectedWidgetNameAndLabel(selectedWidget, newName, newLabel) {
349
+ this.selectedWidgetName = newName;
350
+ //selectedWidget.options.name = newName //此行多余
351
+ if (
352
+ !!newLabel &&
353
+ Object.keys(selectedWidget.options).indexOf("label") > -1
354
+ ) {
355
+ selectedWidget.options.label = newLabel;
356
+ }
357
+ },
358
+
359
+ clearSelected() {
360
+ this.selectedId = null;
361
+ this.selectedWidgetName = null;
362
+ this.selectedWidget = {}; //this.selectedWidget = null
363
+ },
364
+
365
+ checkWidgetMove(evt) {
366
+ /* Only field widget can be dragged into sub-form */
367
+ if (!!evt.draggedContext && !!evt.draggedContext.element) {
368
+ let wgCategory = evt.draggedContext.element.category;
369
+ let wgType = evt.draggedContext.element.type;
370
+ if (!!evt.to) {
371
+ if (
372
+ evt.to.className === "sub-form-table" &&
373
+ wgCategory === "container"
374
+ ) {
375
+ //this.$message.info(this.vueInstance.i18nt('designer.hint.onlyFieldWidgetAcceptable'))
376
+ return false;
377
+ }
378
+ }
379
+ }
380
+
381
+ return true;
382
+ },
383
+
384
+ checkFieldMove(evt) {
385
+ if (!!evt.draggedContext && !!evt.draggedContext.element) {
386
+ let wgCategory = evt.draggedContext.element.category;
387
+ let wgType = evt.draggedContext.element.type + "";
388
+ //console.log('wgType======', wgType)
389
+ if (!!evt.to) {
390
+ if (evt.to.className === "sub-form-table" && wgType === "slot") {
391
+ //this.$message.info(this.vueInstance.i18nt('designer.hint.onlyFieldWidgetAcceptable'))
392
+ return false;
393
+ }
394
+ }
395
+ }
396
+
397
+ return true;
398
+ },
399
+
400
+ /**
401
+ * 追加表格新行
402
+ * @param widget
403
+ */
404
+ appendTableRow(widget) {
405
+ let rowIdx = widget.rows.length; //确定插入行位置
406
+ let newRow = baseRefUtil.deepClone(widget.rows[widget.rows.length - 1]);
407
+ newRow.id = "table-row-" + baseRefUtil.generateId();
408
+ newRow.merged = false;
409
+ newRow.cols.forEach((col) => {
410
+ col.id = "table-cell-" + baseRefUtil.generateId();
411
+ col.options.name = col.id;
412
+ col.merged = false;
413
+ col.options.colspan = 1;
414
+ col.options.rowspan = 1;
415
+ col.widgetList.length = 0;
416
+ });
417
+ widget.rows.splice(rowIdx, 0, newRow);
418
+
419
+ this.emitHistoryChange();
420
+ },
421
+
422
+ /**
423
+ * 追加表格新列
424
+ * @param widget
425
+ */
426
+ appendTableCol(widget) {
427
+ let colIdx = widget.rows[0].cols.length; //确定插入列位置
428
+ widget.rows.forEach((row) => {
429
+ let newCol = baseRefUtil.deepClone(
430
+ this.getContainerByType("table-cell")
431
+ );
432
+ newCol.id = "table-cell-" + baseRefUtil.generateId();
433
+ newCol.options.name = newCol.id;
434
+ newCol.merged = false;
435
+ newCol.options.colspan = 1;
436
+ newCol.options.rowspan = 1;
437
+ newCol.widgetList.length = 0;
438
+ row.cols.splice(colIdx, 0, newCol);
439
+ });
440
+
441
+ this.emitHistoryChange();
442
+ },
443
+
444
+ insertTableRow(widget, insertPos, cloneRowIdx, curCol, aboveFlag) {
445
+ let newRowIdx = !!aboveFlag ? insertPos : insertPos + 1; //初步确定插入行位置
446
+ if (!aboveFlag) {
447
+ //继续向下寻找同列第一个未被合并的单元格
448
+ let tmpRowIdx = newRowIdx;
449
+ let rowFoundFlag = false;
450
+ while (tmpRowIdx < widget.rows.length) {
451
+ if (!widget.rows[tmpRowIdx].cols[curCol].merged) {
452
+ newRowIdx = tmpRowIdx;
453
+ rowFoundFlag = true;
454
+ break;
455
+ } else {
456
+ tmpRowIdx++;
457
+ }
458
+ }
459
+
460
+ if (!rowFoundFlag) {
461
+ newRowIdx = widget.rows.length;
462
+ }
463
+ }
464
+
465
+ let newRow = baseRefUtil.deepClone(widget.rows[cloneRowIdx]);
466
+ newRow.id = "table-row-" + baseRefUtil.generateId();
467
+ newRow.merged = false;
468
+ newRow.cols.forEach((col) => {
469
+ col.id = "table-cell-" + baseRefUtil.generateId();
470
+ col.options.name = col.id;
471
+ col.merged = false;
472
+ col.options.colspan = 1;
473
+ col.options.rowspan = 1;
474
+ col.widgetList.length = 0;
475
+ });
476
+ widget.rows.splice(newRowIdx, 0, newRow);
477
+
478
+ let colNo = 0;
479
+ while (
480
+ newRowIdx < widget.rows.length - 1 &&
481
+ colNo < widget.rows[0].cols.length
482
+ ) {
483
+ //越界判断
484
+ const cellOfNextRow = widget.rows[newRowIdx + 1].cols[colNo];
485
+ const rowMerged = cellOfNextRow.merged; //确定插入位置下一行的单元格是否为合并单元格
486
+ if (!!rowMerged) {
487
+ let rowArray = widget.rows;
488
+ let unMergedCell = {};
489
+ let startRowIndex = null;
490
+ for (let i = newRowIdx; i >= 0; i--) {
491
+ //查找该行已合并的主单元格
492
+ if (
493
+ !rowArray[i].cols[colNo].merged &&
494
+ rowArray[i].cols[colNo].options.rowspan > 1
495
+ ) {
496
+ startRowIndex = i;
497
+ unMergedCell = rowArray[i].cols[colNo];
498
+ break;
499
+ }
500
+ }
501
+
502
+ if (!!unMergedCell.options) {
503
+ //如果有符合条件的unMergedCell
504
+ let newRowspan = unMergedCell.options.rowspan + 1;
505
+ this.setPropsOfMergedRows(
506
+ widget.rows,
507
+ startRowIndex,
508
+ colNo,
509
+ unMergedCell.options.colspan,
510
+ newRowspan
511
+ );
512
+ colNo += unMergedCell.options.colspan;
513
+ } else {
514
+ colNo += 1;
515
+ }
516
+ } else {
517
+ //colNo += 1
518
+ colNo += cellOfNextRow.options.colspan || 1;
519
+ }
520
+ }
521
+
522
+ this.emitHistoryChange();
523
+ },
524
+
525
+ insertTableCol(widget, insertPos, curRow, leftFlag) {
526
+ let newColIdx = !!leftFlag ? insertPos : insertPos + 1; //初步确定插入列位置
527
+ if (!leftFlag) {
528
+ //继续向右寻找同行第一个未被合并的单元格
529
+ let tmpColIdx = newColIdx;
530
+ let colFoundFlag = false;
531
+ while (tmpColIdx < widget.rows[curRow].cols.length) {
532
+ if (!widget.rows[curRow].cols[tmpColIdx].merged) {
533
+ newColIdx = tmpColIdx;
534
+ colFoundFlag = true;
535
+ break;
536
+ } else {
537
+ tmpColIdx++;
538
+ }
539
+
540
+ if (!colFoundFlag) {
541
+ newColIdx = widget.rows[curRow].cols.length;
542
+ }
543
+ }
544
+ }
545
+
546
+ widget.rows.forEach((row) => {
547
+ let newCol = baseRefUtil.deepClone(
548
+ this.getContainerByType("table-cell")
549
+ );
550
+ newCol.id = "table-cell-" + baseRefUtil.generateId();
551
+ newCol.options.name = newCol.id;
552
+ newCol.merged = false;
553
+ newCol.options.colspan = 1;
554
+ newCol.options.rowspan = 1;
555
+ newCol.widgetList.length = 0;
556
+ row.cols.splice(newColIdx, 0, newCol);
557
+ });
558
+
559
+ let rowNo = 0;
560
+ while (
561
+ newColIdx < widget.rows[0].cols.length - 1 &&
562
+ rowNo < widget.rows.length
563
+ ) {
564
+ //越界判断
565
+ const cellOfNextCol = widget.rows[rowNo].cols[newColIdx + 1];
566
+ const colMerged = cellOfNextCol.merged; //确定插入位置右侧列的单元格是否为合并单元格
567
+ if (!!colMerged) {
568
+ let colArray = widget.rows[rowNo].cols;
569
+ let unMergedCell = {};
570
+ let startColIndex = null;
571
+ for (let i = newColIdx; i >= 0; i--) {
572
+ //查找该行已合并的主单元格
573
+ if (!colArray[i].merged && colArray[i].options.colspan > 1) {
574
+ startColIndex = i;
575
+ unMergedCell = colArray[i];
576
+ break;
577
+ }
578
+ }
579
+
580
+ if (!!unMergedCell.options) {
581
+ //如果有符合条件的unMergedCell
582
+ let newColspan = unMergedCell.options.colspan + 1;
583
+ this.setPropsOfMergedCols(
584
+ widget.rows,
585
+ rowNo,
586
+ startColIndex,
587
+ newColspan,
588
+ unMergedCell.options.rowspan
589
+ );
590
+ rowNo += unMergedCell.options.rowspan;
591
+ } else {
592
+ rowNo += 1;
593
+ }
594
+ } else {
595
+ //rowNo += 1
596
+ rowNo += cellOfNextCol.options.rowspan || 1;
597
+ }
598
+ }
599
+
600
+ this.emitHistoryChange();
601
+ },
602
+ insertH5TableCol(widget, insertPos, curRow, leftFlag) {
603
+ let newColIdx = !!leftFlag ? insertPos : insertPos + 1; //初步确定插入列位置
604
+ if (!leftFlag) {
605
+ //继续向右寻找同行第一个未被合并的单元格
606
+ let tmpColIdx = newColIdx;
607
+ let colFoundFlag = false;
608
+ while (tmpColIdx < widget.rows[curRow].cols.length) {
609
+ if (!widget.rows[curRow].cols[tmpColIdx].merged) {
610
+ newColIdx = tmpColIdx;
611
+ colFoundFlag = true;
612
+ break;
613
+ } else {
614
+ tmpColIdx++;
615
+ }
616
+
617
+ if (!colFoundFlag) {
618
+ newColIdx = widget.rows[curRow].cols.length;
619
+ }
620
+ }
621
+ }
622
+
623
+ widget.rows.forEach((row) => {
624
+ let newCol = baseRefUtil.deepClone(
625
+ this.getContainerByType("h5-table-cell")
626
+ );
627
+ newCol.id = "table-cell-" + baseRefUtil.generateId();
628
+ newCol.options.name = newCol.id;
629
+ newCol.merged = false;
630
+ newCol.options.colspan = 1;
631
+ newCol.options.rowspan = 1;
632
+ newCol.widgetList.length = 0;
633
+ row.cols.splice(newColIdx, 0, newCol);
634
+ });
635
+
636
+ let rowNo = 0;
637
+ while (
638
+ newColIdx < widget.rows[0].cols.length - 1 &&
639
+ rowNo < widget.rows.length
640
+ ) {
641
+ //越界判断
642
+ const cellOfNextCol = widget.rows[rowNo].cols[newColIdx + 1];
643
+ const colMerged = cellOfNextCol.merged; //确定插入位置右侧列的单元格是否为合并单元格
644
+ if (!!colMerged) {
645
+ let colArray = widget.rows[rowNo].cols;
646
+ let unMergedCell = {};
647
+ let startColIndex = null;
648
+ for (let i = newColIdx; i >= 0; i--) {
649
+ //查找该行已合并的主单元格
650
+ if (!colArray[i].merged && colArray[i].options.colspan > 1) {
651
+ startColIndex = i;
652
+ unMergedCell = colArray[i];
653
+ break;
654
+ }
655
+ }
656
+
657
+ if (!!unMergedCell.options) {
658
+ //如果有符合条件的unMergedCell
659
+ let newColspan = unMergedCell.options.colspan + 1;
660
+ this.setPropsOfMergedCols(
661
+ widget.rows,
662
+ rowNo,
663
+ startColIndex,
664
+ newColspan,
665
+ unMergedCell.options.rowspan
666
+ );
667
+ rowNo += unMergedCell.options.rowspan;
668
+ } else {
669
+ rowNo += 1;
670
+ }
671
+ } else {
672
+ //rowNo += 1
673
+ rowNo += cellOfNextCol.options.rowspan || 1;
674
+ }
675
+ }
676
+
677
+ this.emitHistoryChange();
678
+ },
679
+ setPropsOfMergedCols(
680
+ rowArray,
681
+ startRowIndex,
682
+ startColIndex,
683
+ newColspan,
684
+ rowspan
685
+ ) {
686
+ for (let i = startRowIndex; i < startRowIndex + rowspan; i++) {
687
+ for (let j = startColIndex; j < startColIndex + newColspan; j++) {
688
+ if (i === startRowIndex && j === startColIndex) {
689
+ rowArray[i].cols[j].options.colspan = newColspan; //合并后的主单元格
690
+ continue;
691
+ }
692
+
693
+ rowArray[i].cols[j].merged = true;
694
+ rowArray[i].cols[j].options.colspan = newColspan;
695
+ rowArray[i].cols[j].widgetList = [];
696
+ }
697
+ }
698
+ },
699
+
700
+ setPropsOfMergedRows(
701
+ rowArray,
702
+ startRowIndex,
703
+ startColIndex,
704
+ colspan,
705
+ newRowspan
706
+ ) {
707
+ for (let i = startRowIndex; i < startRowIndex + newRowspan; i++) {
708
+ for (let j = startColIndex; j < startColIndex + colspan; j++) {
709
+ if (i === startRowIndex && j === startColIndex) {
710
+ rowArray[i].cols[j].options.rowspan = newRowspan;
711
+ continue;
712
+ }
713
+
714
+ rowArray[i].cols[j].merged = true;
715
+ rowArray[i].cols[j].options.rowspan = newRowspan;
716
+ rowArray[i].cols[j].widgetList = [];
717
+ }
718
+ }
719
+ },
720
+
721
+ setPropsOfSplitCol(
722
+ rowArray,
723
+ startRowIndex,
724
+ startColIndex,
725
+ colspan,
726
+ rowspan
727
+ ) {
728
+ for (let i = startRowIndex; i < startRowIndex + rowspan; i++) {
729
+ for (let j = startColIndex; j < startColIndex + colspan; j++) {
730
+ rowArray[i].cols[j].merged = false;
731
+ rowArray[i].cols[j].options.rowspan = 1;
732
+ rowArray[i].cols[j].options.colspan = 1;
733
+ }
734
+ }
735
+ },
736
+
737
+ setPropsOfSplitRow(
738
+ rowArray,
739
+ startRowIndex,
740
+ startColIndex,
741
+ colspan,
742
+ rowspan
743
+ ) {
744
+ for (let i = startRowIndex; i < startRowIndex + rowspan; i++) {
745
+ for (let j = startColIndex; j < startColIndex + colspan; j++) {
746
+ rowArray[i].cols[j].merged = false;
747
+ rowArray[i].cols[j].options.rowspan = 1;
748
+ rowArray[i].cols[j].options.colspan = 1;
749
+ }
750
+ }
751
+ },
752
+
753
+ mergeTableCol(rowArray, colArray, curRow, curCol, leftFlag, cellWidget) {
754
+ let mergedColIdx = !!leftFlag
755
+ ? curCol
756
+ : curCol + colArray[curCol].options.colspan;
757
+
758
+ // let remainedColIdx = !!leftFlag ? curCol - colArray[curCol - 1].options.colspan : curCol
759
+ let remainedColIdx = !!leftFlag ? curCol - 1 : curCol;
760
+ if (!!leftFlag) {
761
+ //继续向左寻找同行未被合并的第一个单元格
762
+ let tmpColIdx = remainedColIdx;
763
+ while (tmpColIdx >= 0) {
764
+ if (!rowArray[curRow].cols[tmpColIdx].merged) {
765
+ remainedColIdx = tmpColIdx;
766
+ break;
767
+ } else {
768
+ tmpColIdx--;
769
+ }
770
+ }
771
+ }
772
+
773
+ if (
774
+ !!colArray[mergedColIdx].widgetList &&
775
+ colArray[mergedColIdx].widgetList.length > 0
776
+ ) {
777
+ //保留widgetList
778
+ if (
779
+ !colArray[remainedColIdx].widgetList ||
780
+ colArray[remainedColIdx].widgetList.length === 0
781
+ ) {
782
+ colArray[remainedColIdx].widgetList = baseRefUtil.deepClone(
783
+ colArray[mergedColIdx].widgetList
784
+ );
785
+ }
786
+ }
787
+
788
+ let newColspan =
789
+ colArray[mergedColIdx].options.colspan * 1 +
790
+ colArray[remainedColIdx].options.colspan * 1;
791
+ this.setPropsOfMergedCols(
792
+ rowArray,
793
+ curRow,
794
+ remainedColIdx,
795
+ newColspan,
796
+ cellWidget.options.rowspan
797
+ );
798
+
799
+ this.emitHistoryChange();
800
+ },
801
+
802
+ mergeTableWholeRow(rowArray, colArray, rowIndex, colIndex) {
803
+ //需要考虑操作的行存在已合并的单元格!!
804
+ //整行所有单元格行高不一致不可合并!!
805
+ let startRowspan = rowArray[rowIndex].cols[0].options.rowspan;
806
+ let unmatchedFlag = false;
807
+ for (let i = 1; i < rowArray[rowIndex].cols.length; i++) {
808
+ if (rowArray[rowIndex].cols[i].options.rowspan !== startRowspan) {
809
+ unmatchedFlag = true;
810
+ break;
811
+ }
812
+ }
813
+ if (unmatchedFlag) {
814
+ this.vueInstance.$message.info(
815
+ this.vueInstance.i18nt(
816
+ "designer.hint.rowspanNotConsistentForMergeEntireRow"
817
+ )
818
+ );
819
+ return;
820
+ }
821
+
822
+ let widgetListCols = colArray.filter((colItem) => {
823
+ return (
824
+ !colItem.merged &&
825
+ !!colItem.widgetList &&
826
+ colItem.widgetList.length > 0
827
+ );
828
+ });
829
+ if (!!widgetListCols && widgetListCols.length > 0) {
830
+ //保留widgetList
831
+ if (
832
+ widgetListCols[0].id !== colArray[0].id &&
833
+ (!colArray[0].widgetList || colArray[0].widgetList.length <= 0)
834
+ ) {
835
+ colArray[0].widgetList = baseRefUtil.deepClone(
836
+ widgetListCols[0].widgetList
837
+ );
838
+ }
839
+ }
840
+
841
+ this.setPropsOfMergedCols(
842
+ rowArray,
843
+ rowIndex,
844
+ 0,
845
+ colArray.length,
846
+ colArray[colIndex].options.rowspan
847
+ );
848
+
849
+ this.emitHistoryChange();
850
+ },
851
+
852
+ mergeTableRow(rowArray, curRow, curCol, aboveFlag, cellWidget) {
853
+ let mergedRowIdx = !!aboveFlag
854
+ ? curRow
855
+ : curRow + cellWidget.options.rowspan;
856
+
857
+ //let remainedRowIdx = !!aboveFlag ? curRow - cellWidget.options.rowspan : curRow
858
+ let remainedRowIdx = !!aboveFlag ? curRow - 1 : curRow;
859
+ if (!!aboveFlag) {
860
+ //继续向上寻找同列未被合并的第一个单元格
861
+ let tmpRowIdx = remainedRowIdx;
862
+ while (tmpRowIdx >= 0) {
863
+ if (!rowArray[tmpRowIdx].cols[curCol].merged) {
864
+ remainedRowIdx = tmpRowIdx;
865
+ break;
866
+ } else {
867
+ tmpRowIdx--;
868
+ }
869
+ }
870
+ }
871
+
872
+ if (
873
+ !!rowArray[mergedRowIdx].cols[curCol].widgetList &&
874
+ rowArray[mergedRowIdx].cols[curCol].widgetList.length > 0
875
+ ) {
876
+ //保留widgetList
877
+ if (
878
+ !rowArray[remainedRowIdx].cols[curCol].widgetList ||
879
+ rowArray[remainedRowIdx].cols[curCol].widgetList.length === 0
880
+ ) {
881
+ rowArray[remainedRowIdx].cols[curCol].widgetList =
882
+ baseRefUtil.deepClone(
883
+ rowArray[mergedRowIdx].cols[curCol].widgetList
884
+ );
885
+ }
886
+ }
887
+
888
+ let newRowspan =
889
+ rowArray[mergedRowIdx].cols[curCol].options.rowspan * 1 +
890
+ rowArray[remainedRowIdx].cols[curCol].options.rowspan * 1;
891
+ this.setPropsOfMergedRows(
892
+ rowArray,
893
+ remainedRowIdx,
894
+ curCol,
895
+ cellWidget.options.colspan,
896
+ newRowspan
897
+ );
898
+
899
+ this.emitHistoryChange();
900
+ },
901
+
902
+ mergeTableWholeCol(rowArray, colArray, rowIndex, colIndex) {
903
+ //需要考虑操作的列存在已合并的单元格!!
904
+ //整列所有单元格列宽不一致不可合并!!
905
+ let startColspan = rowArray[0].cols[colIndex].options.colspan;
906
+ let unmatchedFlag = false;
907
+ for (let i = 1; i < rowArray.length; i++) {
908
+ if (rowArray[i].cols[colIndex].options.colspan !== startColspan) {
909
+ unmatchedFlag = true;
910
+ break;
911
+ }
912
+ }
913
+ if (unmatchedFlag) {
914
+ this.vueInstance.$message.info(
915
+ this.vueInstance.i18nt(
916
+ "designer.hint.colspanNotConsistentForMergeEntireColumn"
917
+ )
918
+ );
919
+ return;
920
+ }
921
+
922
+ let widgetListCols = [];
923
+ rowArray.forEach((rowItem) => {
924
+ let tempCell = rowItem.cols[colIndex];
925
+ if (
926
+ !tempCell.merged &&
927
+ !!tempCell.widgetList &&
928
+ tempCell.widgetList.length > 0
929
+ ) {
930
+ widgetListCols.push(tempCell);
931
+ }
932
+ });
933
+
934
+ let firstCellOfCol = rowArray[0].cols[colIndex];
935
+ if (!!widgetListCols && widgetListCols.length > 0) {
936
+ //保留widgetList
937
+ if (
938
+ widgetListCols[0].id !== firstCellOfCol.id &&
939
+ (!firstCellOfCol.widgetList ||
940
+ firstCellOfCol.widgetList.length <= 0)
941
+ ) {
942
+ firstCellOfCol.widgetList = baseRefUtil.deepClone(
943
+ widgetListCols[0].widgetList
944
+ );
945
+ }
946
+ }
947
+
948
+ this.setPropsOfMergedRows(
949
+ rowArray,
950
+ 0,
951
+ colIndex,
952
+ firstCellOfCol.options.colspan,
953
+ rowArray.length
954
+ );
955
+
956
+ this.emitHistoryChange();
957
+ },
958
+
959
+ undoMergeTableCol(rowArray, rowIndex, colIndex, colspan, rowspan) {
960
+ this.setPropsOfSplitCol(rowArray, rowIndex, colIndex, colspan, rowspan);
961
+
962
+ this.emitHistoryChange();
963
+ },
964
+
965
+ undoMergeTableRow(rowArray, rowIndex, colIndex, colspan, rowspan) {
966
+ this.setPropsOfSplitRow(rowArray, rowIndex, colIndex, colspan, rowspan);
967
+
968
+ this.emitHistoryChange();
969
+ },
970
+
971
+ deleteTableWholeCol(rowArray, colIndex) {
972
+ //需考虑删除的是合并列!!
973
+ let onlyOneColFlag = true;
974
+ rowArray.forEach((ri) => {
975
+ if (ri.cols[0].options.colspan !== rowArray[0].cols.length) {
976
+ onlyOneColFlag = false;
977
+ }
978
+ });
979
+ //仅剩一列则不可删除!!
980
+ if (onlyOneColFlag) {
981
+ this.vueInstance.$message.info(
982
+ this.vueInstance.i18nt("designer.hint.lastColCannotBeDeleted")
983
+ );
984
+ return;
985
+ }
986
+
987
+ //整列所有单元格列宽不一致不可删除!!
988
+ let startColspan = rowArray[0].cols[colIndex].options.colspan;
989
+ let unmatchedFlag = false;
990
+ for (let i = 1; i < rowArray.length; i++) {
991
+ if (rowArray[i].cols[colIndex].options.colspan !== startColspan) {
992
+ unmatchedFlag = true;
993
+ break;
994
+ }
995
+ }
996
+ if (unmatchedFlag) {
997
+ this.vueInstance.$message.info(
998
+ this.vueInstance.i18nt(
999
+ "designer.hint.colspanNotConsistentForDeleteEntireColumn"
1000
+ )
1001
+ );
1002
+ return;
1003
+ }
1004
+
1005
+ rowArray.forEach((rItem) => {
1006
+ rItem.cols.splice(colIndex, startColspan);
1007
+ });
1008
+
1009
+ this.emitHistoryChange();
1010
+ },
1011
+
1012
+ deleteTableWholeRow(rowArray, rowIndex) {
1013
+ //需考虑删除的是合并行!!
1014
+ let onlyOneRowFlag = true;
1015
+ rowArray[0].cols.forEach((ci) => {
1016
+ if (ci.options.rowspan !== rowArray.length) {
1017
+ onlyOneRowFlag = false;
1018
+ }
1019
+ });
1020
+ //仅剩一行则不可删除!!
1021
+ if (onlyOneRowFlag) {
1022
+ this.vueInstance.$message.info(
1023
+ this.vueInstance.i18nt("designer.hint.lastRowCannotBeDeleted")
1024
+ );
1025
+ return;
1026
+ }
1027
+
1028
+ //整行所有单元格行高不一致不可删除!!
1029
+ let startRowspan = rowArray[rowIndex].cols[0].options.rowspan;
1030
+ let unmatchedFlag = false;
1031
+ for (let i = 1; i < rowArray[rowIndex].cols.length; i++) {
1032
+ if (rowArray[rowIndex].cols[i].options.rowspan !== startRowspan) {
1033
+ unmatchedFlag = true;
1034
+ break;
1035
+ }
1036
+ }
1037
+ if (unmatchedFlag) {
1038
+ this.vueInstance.$message.info(
1039
+ this.vueInstance.i18nt(
1040
+ "designer.hint.rowspanNotConsistentForDeleteEntireRow"
1041
+ )
1042
+ );
1043
+ return;
1044
+ }
1045
+
1046
+ rowArray.splice(rowIndex, startRowspan);
1047
+
1048
+ this.emitHistoryChange();
1049
+ },
1050
+
1051
+ getContainerByType(typeName) {
1052
+ let allWidgets = [
1053
+ ...baseRefUtil.containers,
1054
+ ...baseRefUtil.basicFields,
1055
+ ...baseRefUtil.advancedFields,
1056
+ ...baseRefUtil.customFields,
1057
+ ...businessFields,
1058
+ ];
1059
+ let foundCon = null;
1060
+ allWidgets.forEach((con) => {
1061
+ if (!!con.category && !!con.type && con.type === typeName) {
1062
+ foundCon = con;
1063
+ }
1064
+ });
1065
+
1066
+ return foundCon;
1067
+ },
1068
+
1069
+ getFieldWidgetByType(typeName) {
1070
+ let allWidgets = [
1071
+ ...baseRefUtil.containers,
1072
+ ...baseRefUtil.basicFields,
1073
+ ...baseRefUtil.advancedFields,
1074
+ ...baseRefUtil.customFields,
1075
+ ...chartContainers,
1076
+ ...chartWidgets,
1077
+ ...businessFields,
1078
+ ];
1079
+ let foundWidget = null;
1080
+ allWidgets.forEach((widget) => {
1081
+ if (!!!widget.category && !!widget.type && widget.type === typeName) {
1082
+ foundWidget = widget;
1083
+ }
1084
+ });
1085
+
1086
+ return foundWidget;
1087
+ },
1088
+
1089
+ hasConfig(widget, configName) {
1090
+ let originalWidget = null;
1091
+ if (!!widget.category) {
1092
+ originalWidget = this.getContainerByType(widget.type);
1093
+ } else {
1094
+ originalWidget = this.getFieldWidgetByType(widget.type);
1095
+ }
1096
+
1097
+ if (!originalWidget || !originalWidget.options) {
1098
+ return false;
1099
+ }
1100
+
1101
+ return Object.keys(originalWidget.options).indexOf(configName) > -1;
1102
+ },
1103
+ /*upgradeWidgetConfig(oldWidget) {
1104
+ let newWidget = null;
1105
+ if (!!oldWidget.category) {
1106
+ newWidget = this.getContainerByType(oldWidget.type);
1107
+ } else {
1108
+ newWidget = this.getFieldWidgetByType(oldWidget.type);
1109
+ }
1110
+
1111
+ if (!newWidget || !newWidget.options) {
1112
+ return;
1113
+ }
1114
+
1115
+ Object.keys(newWidget.options).forEach(ck => {
1116
+ if (!oldWidget.options.hasOwnProperty(ck)) {
1117
+ oldWidget.options[ck] = baseRefUtil.deepClone(newWidget.options[ck]);
1118
+ }
1119
+ });
1120
+ },*/
1121
+ upgradeWidgetConfig(oldWidget) {
1122
+ let newWidget = null;
1123
+ if (!!oldWidget.category) {
1124
+ newWidget = this.getContainerByType(oldWidget.type);
1125
+ } else {
1126
+ newWidget = this.getFieldWidgetByType(oldWidget.type);
1127
+ }
1128
+
1129
+ if (!newWidget || !newWidget.options) {
1130
+ return;
1131
+ }
1132
+
1133
+ Object.keys(newWidget.options).forEach((ck) => {
1134
+ if (!oldWidget.options.hasOwnProperty(ck)) {
1135
+ let value = newWidget.options[ck];
1136
+ let nullValue = Array.isArray(value) ? [] : null;
1137
+ oldWidget.options[ck] = nullValue;
1138
+ }
1139
+ });
1140
+ },
1141
+
1142
+ upgradeFormConfig(oldFormConfig) {
1143
+ Object.keys(this.formConfig).forEach((fc) => {
1144
+ if (!oldFormConfig.hasOwnProperty(fc)) {
1145
+ let value = this.formConfig[fc];
1146
+ let nullValue = Array.isArray(value) ? [] : null;
1147
+ oldFormConfig[fc] = baseRefUtil.deepClone(nullValue);
1148
+ }
1149
+ });
1150
+ },
1151
+
1152
+ cloneGridCol(widget, parentWidget) {
1153
+ let newGridCol = baseRefUtil.deepClone(
1154
+ this.getContainerByType("grid-col")
1155
+ );
1156
+ newGridCol.options.span = widget.options.span;
1157
+ let tmpId = baseRefUtil.generateId();
1158
+ newGridCol.id = "grid-col-" + tmpId;
1159
+ newGridCol.options.name = "gridCol" + tmpId;
1160
+
1161
+ parentWidget.cols.push(newGridCol);
1162
+ },
1163
+
1164
+ cloneContainer(containWidget) {
1165
+ if (containWidget.type === "grid") {
1166
+ let newGrid = baseRefUtil.deepClone(this.getContainerByType("grid"));
1167
+ newGrid.id = newGrid.type + baseRefUtil.generateId();
1168
+ newGrid.options.name = newGrid.id;
1169
+ containWidget.cols.forEach((gridCol) => {
1170
+ let newGridCol = baseRefUtil.deepClone(
1171
+ this.getContainerByType("grid-col")
1172
+ );
1173
+ let tmpId = baseRefUtil.generateId();
1174
+ newGridCol.id = "grid-col-" + tmpId;
1175
+ newGridCol.options.name = "gridCol" + tmpId;
1176
+ newGridCol.options.span = gridCol.options.span;
1177
+ newGrid.cols.push(newGridCol);
1178
+ });
1179
+
1180
+ return newGrid;
1181
+ } else if (containWidget.type === "table") {
1182
+ let newTable = baseRefUtil.deepClone(
1183
+ this.getContainerByType("table")
1184
+ );
1185
+ newTable.id = newTable.type + baseRefUtil.generateId();
1186
+ newTable.options.name = newTable.id;
1187
+ containWidget.rows.forEach((tRow) => {
1188
+ let newRow = baseRefUtil.deepClone(tRow);
1189
+ newRow.id = "table-row-" + baseRefUtil.generateId();
1190
+ newRow.cols.forEach((col) => {
1191
+ col.id = "table-cell-" + baseRefUtil.generateId();
1192
+ col.options.name = col.id;
1193
+ col.widgetList = []; //清空组件列表
1194
+ });
1195
+ newTable.rows.push(newRow);
1196
+ });
1197
+
1198
+ return newTable;
1199
+ } else if (containWidget.type === "h5-table") {
1200
+ let newTable = baseRefUtil.deepClone(
1201
+ this.getContainerByType("h5-table")
1202
+ );
1203
+ newTable.id = newTable.type + baseRefUtil.generateId();
1204
+ newTable.options.name = newTable.id;
1205
+ containWidget.rows.forEach((tRow) => {
1206
+ let newRow = baseRefUtil.deepClone(tRow);
1207
+ newRow.id = "table-row-" + baseRefUtil.generateId();
1208
+ newRow.cols.forEach((col) => {
1209
+ col.id = "table-cell-" + baseRefUtil.generateId();
1210
+ col.options.name = col.id;
1211
+ col.widgetList = []; //清空组件列表
1212
+ });
1213
+ newTable.rows.push(newRow);
1214
+ });
1215
+
1216
+ return newTable;
1217
+ } else {
1218
+ //其他容器组件不支持clone操作
1219
+ return null;
1220
+ }
1221
+ },
1222
+
1223
+ moveUpWidget(parentList, indexOfParentList) {
1224
+ if (!!parentList) {
1225
+ if (indexOfParentList === 0) {
1226
+ this.vueInstance.$message(
1227
+ this.vueInstance.i18nt("designer.hint.moveUpFirstChildHint")
1228
+ );
1229
+ return;
1230
+ }
1231
+
1232
+ let tempWidget = parentList[indexOfParentList];
1233
+ parentList.splice(indexOfParentList, 1);
1234
+ parentList.splice(indexOfParentList - 1, 0, tempWidget);
1235
+ }
1236
+ },
1237
+
1238
+ moveDownWidget(parentList, indexOfParentList) {
1239
+ if (!!parentList) {
1240
+ if (indexOfParentList === parentList.length - 1) {
1241
+ this.vueInstance.$message(
1242
+ this.vueInstance.i18nt("designer.hint.moveDownLastChildHint")
1243
+ );
1244
+ return;
1245
+ }
1246
+
1247
+ let tempWidget = parentList[indexOfParentList];
1248
+ parentList.splice(indexOfParentList, 1);
1249
+ parentList.splice(indexOfParentList + 1, 0, tempWidget);
1250
+ }
1251
+ },
1252
+ copyNewFieldWidget(origin) {
1253
+ let newWidget = baseRefUtil.deepClone(origin);
1254
+ let sourceType = newWidget.type;
1255
+ newWidget.type = newWidget.targetType || newWidget.type;
1256
+ newWidget.sourceType = sourceType;
1257
+ let tempId = baseRefUtil.generateId();
1258
+ newWidget.id = newWidget.type.replace(/-/g, "") + tempId;
1259
+ if (newWidget.hasOwnProperty("tableField")) {
1260
+ newWidget.tableField = newWidget.id; //表字段
1261
+ }
1262
+
1263
+ // newWidget.options.name = newWidget.id;
1264
+ // newWidget.options.label = newWidget.options.label || newWidget.type.toLowerCase();
1265
+
1266
+ newWidget.nameReadonly
1267
+ ? newWidget.options.label &&
1268
+ newWidget.options.label.indexOf(".") > -1 &&
1269
+ (newWidget.options.label = newWidget.options.label.substring(
1270
+ newWidget.options.label.indexOf(".") + 1
1271
+ ))
1272
+ : ((newWidget.options.name = newWidget.id),
1273
+ (newWidget.options.label =
1274
+ newWidget.options.label || newWidget.type.toLowerCase()));
1275
+ delete newWidget.displayName;
1276
+ if (!newWidget.nameReadonly) {
1277
+ newWidget.options.keyNameEnabled = true;
1278
+ if (!newWidget.options.keyName)
1279
+ newWidget.options.keyName = newWidget.id;
1280
+ if (
1281
+ newWidget.type === "vabUpload" ||
1282
+ newWidget.type === "baseAttachment"
1283
+ ) {
1284
+ let keyNameSuffix = this.createKeyNameSuffix(newWidget.type);
1285
+ // this.createKeyNameSuffix()
1286
+ newWidget.options.keyName = this.createKeyName(
1287
+ newWidget.type,
1288
+ keyNameSuffix
1289
+ );
1290
+ newWidget.options.keyNameSuffix = keyNameSuffix;
1291
+ }
1292
+ }
1293
+ if (newWidget.type === "dropdown") {
1294
+ let dropdownItem1 = this.copyNewFieldWidget(
1295
+ this.getFieldWidgetByType("dropdown-item")
1296
+ );
1297
+ dropdownItem1.options.label = "下拉按钮1";
1298
+ let dropdownItem2 = this.copyNewFieldWidget(
1299
+ this.getFieldWidgetByType("dropdown-item")
1300
+ );
1301
+ dropdownItem2.options.label = "下拉按钮2";
1302
+ newWidget.widgetList.push(dropdownItem1);
1303
+ newWidget.widgetList.push(dropdownItem2);
1304
+ }
1305
+ this.emitEvent("canvas-add-field", newWidget.options.name);
1306
+ return newWidget;
1307
+ },
1308
+ createKeyName(type, suffix, options) {
1309
+ let keyNameSuffix = suffix ? suffix : this.createKeyNameSuffix(type);
1310
+ let keyNamePrefix = this.getKeyNamePrefix(type, options);
1311
+ let keyName = null;
1312
+ if (keyNamePrefix) {
1313
+ keyName = keyNamePrefix + keyNameSuffix;
1314
+ } else {
1315
+ keyName = keyNameSuffix;
1316
+ }
1317
+ return keyName;
1318
+ },
1319
+ createKeyNameSuffix(type) {
1320
+ let suffix = createUUID();
1321
+ /*if (type === "vabUpload" || type === "baseAttachment") {
1322
+ let formCode = vueInstance.reportTemplate.formCode;
1323
+ suffix = formCode + "_" + suffix;
1324
+ }*/
1325
+ return suffix;
1326
+ },
1327
+ /* 开了「值存为URL」的附件字段存的是主表普通列(值是 URL 字符串),不再走
1328
+ attachments_ 独立附件通道,keyName 不能带前缀——否则保存时会被
1329
+ data-table-mixin attachments_ 提取逻辑当附件包发走,主表列存不到 */
1330
+ getKeyNamePrefix(type, options) {
1331
+ if (options && options.urlValueEnabled) {
1332
+ return null;
1333
+ }
1334
+ return keyNamePrefixMap[type] ?? null;
1335
+ },
1336
+ getFormCodePrefix(type) {
1337
+ let prefix = this.getKeyNamePrefix(type) || "";
1338
+ let attachmentPrefix =
1339
+ prefix + vueInstance.reportTemplate.formCode + "_";
1340
+ return attachmentPrefix;
1341
+ },
1342
+ createAttachmentSuffix() {
1343
+ let type = "vabUpload";
1344
+ return this.createKeyNameSuffix(type);
1345
+ },
1346
+ getAttachmentPrefix() {
1347
+ let type = "vabUpload";
1348
+ return this.getKeyNamePrefix(type);
1349
+ },
1350
+ getAttachmentFormCodePrefix() {
1351
+ let type = "vabUpload";
1352
+ let attachmentPrefix = this.getFormCodePrefix(type);
1353
+ return attachmentPrefix;
1354
+ },
1355
+ createAttachmentKeyName(suffix) {
1356
+ let type = "vabUpload";
1357
+ let keyName = this.createKeyName(type, suffix);
1358
+ return keyName;
1359
+ },
1360
+ copyNewContainerWidget(origin) {
1361
+ let newCon = baseRefUtil.deepClone(origin);
1362
+ let sourceType = newCon.type;
1363
+ newCon.type = newCon.targetType || newCon.type;
1364
+ newCon.sourceType = sourceType;
1365
+ newCon.id = newCon.type.replace(/-/g, "") + baseRefUtil.generateId();
1366
+ newCon.options.name = newCon.id;
1367
+ if ((newCon.options.keyNameEnabled = true)) {
1368
+ newCon.options.keyName = newCon.id;
1369
+ }
1370
+ if (newCon.hasOwnProperty("tableField")) {
1371
+ newCon.tableField = newCon.id; //表字段
1372
+ }
1373
+ if (newCon.type === "grid") {
1374
+ let newCol = baseRefUtil.deepClone(
1375
+ this.getContainerByType("grid-col")
1376
+ );
1377
+ let tmpId = baseRefUtil.generateId();
1378
+ newCol.id = "grid-col-" + tmpId;
1379
+ newCol.options.name = "gridCol" + tmpId;
1380
+ newCon.cols.push(newCol);
1381
+ //
1382
+ newCol = baseRefUtil.deepClone(newCol);
1383
+ tmpId = baseRefUtil.generateId();
1384
+ newCol.id = "grid-col-" + tmpId;
1385
+ newCol.options.name = "gridCol" + tmpId;
1386
+ newCon.cols.push(newCol);
1387
+ } else if (newCon.type === "table") {
1388
+ let newRow = {
1389
+ cols: [],
1390
+ };
1391
+ newRow.id = "table-row-" + baseRefUtil.generateId();
1392
+ newRow.merged = false;
1393
+ for (let i = 0; i < 4; i++) {
1394
+ let newCell = baseRefUtil.deepClone(
1395
+ this.getContainerByType("table-cell")
1396
+ );
1397
+ newCell.id = "table-cell-" + baseRefUtil.generateId();
1398
+ newCell.options.name = newCell.id;
1399
+ newCell.merged = false;
1400
+ newCell.options.colspan = 1;
1401
+ newCell.options.rowspan = 1;
1402
+ newRow.cols.push(newCell);
1403
+ }
1404
+ newCon.rows.push(newRow);
1405
+ } else if (newCon.type === "tab") {
1406
+ let newTabPane = baseRefUtil.deepClone(
1407
+ this.getContainerByType("tab-pane")
1408
+ );
1409
+ newTabPane.id = "tab-pane-" + baseRefUtil.generateId();
1410
+ newTabPane.options.name = "tab1";
1411
+ newTabPane.options.label = "tab 1";
1412
+ newCon.tabs.push(newTabPane);
1413
+ } else if (newCon.type === "data-table") {
1414
+ let add_button = this.copyNewFieldWidget(
1415
+ this.getFieldWidgetByType("add_button")
1416
+ );
1417
+ add_button.options.onClick =
1418
+ "this.getWidgetRef('" +
1419
+ newCon.options.name +
1420
+ "').openEditDialog();";
1421
+ newCon.buttons.push(add_button);
1422
+ } else if (newCon.type === "detail" || newCon.type === "detail-plain") {
1423
+ /* detail-plain 无标题栏,不预置标题栏按钮;其余 panes 结构与 detail 一致 */
1424
+ if (newCon.type === "detail") {
1425
+ let buttonCon1 = this.copyNewFieldWidget(
1426
+ this.getFieldWidgetByType("reset_button")
1427
+ );
1428
+ // buttonCon1.options.label = "重置";
1429
+
1430
+ let buttonCon2 = this.copyNewFieldWidget(
1431
+ this.getFieldWidgetByType("save_button")
1432
+ );
1433
+ buttonCon2.options.label = "保存";
1434
+
1435
+ newCon.widgetList.push(buttonCon1);
1436
+ newCon.widgetList.push(buttonCon2);
1437
+ }
1438
+
1439
+ let newCol = baseRefUtil.deepClone(
1440
+ this.getContainerByType("detail-pane")
1441
+ );
1442
+ let tmpId = baseRefUtil.generateId();
1443
+ newCol.id = "detail-pane-" + tmpId;
1444
+ newCol.options.name = "detailPane" + tmpId;
1445
+ newCol.options.label = "隐藏信息";
1446
+ newCol.options.hidden = true;
1447
+
1448
+ let tableCon = this.copyNewContainerWidget(
1449
+ this.getContainerByType("table")
1450
+ );
1451
+ newCol.widgetList.push(tableCon);
1452
+ newCon.panes.push(newCol);
1453
+
1454
+ newCol = baseRefUtil.deepClone(
1455
+ this.getContainerByType("detail-pane")
1456
+ );
1457
+ tmpId = baseRefUtil.generateId();
1458
+ newCol.id = "detail-pane-" + tmpId;
1459
+ newCol.options.name = "detailPane" + tmpId;
1460
+ newCol.options.label = "基础信息";
1461
+
1462
+ tableCon = this.copyNewContainerWidget(
1463
+ this.getContainerByType("table")
1464
+ );
1465
+ newCol.widgetList.push(tableCon);
1466
+ newCon.panes.push(newCol);
1467
+ //
1468
+ newCol = baseRefUtil.deepClone(
1469
+ this.getContainerByType("detail-pane")
1470
+ );
1471
+ tmpId = baseRefUtil.generateId();
1472
+ newCol.id = "detail-pane-" + tmpId;
1473
+ newCol.options.name = "detailPane" + tmpId;
1474
+ newCol.options.label = "明细信息";
1475
+ newCol.options.tableRef = tableCon.id;
1476
+ let dataTableCon = this.copyNewContainerWidget(
1477
+ this.getContainerByType("data-table")
1478
+ );
1479
+ newCol.widgetList.push(dataTableCon);
1480
+ newCol.options.tableRef = dataTableCon.id;
1481
+
1482
+ let buttonCon3 = this.copyNewFieldWidget(
1483
+ this.getFieldWidgetByType("button")
1484
+ );
1485
+ buttonCon3.options.label = "新增";
1486
+ buttonCon3.options.icon = "el-icon-search";
1487
+ // buttonCon3.options.onClick = "this.getWidgetRef('" + dataTableCon.options.name + "').addTableData();"
1488
+ buttonCon3.options.clickBindEvent = CLICK_BIND.ADD_TABLE_DATA;
1489
+ Object.assign(buttonCon3.options.addTableDataConfig, {
1490
+ tableRef: dataTableCon.options.name,
1491
+ });
1492
+
1493
+ newCol.buttonWidgetList.push(buttonCon3);
1494
+ newCon.panes.push(newCol);
1495
+
1496
+ newCol = baseRefUtil.deepClone(
1497
+ this.getContainerByType("detail-pane")
1498
+ );
1499
+ tmpId = baseRefUtil.generateId();
1500
+ newCol.id = "detail-pane-" + tmpId;
1501
+ newCol.options.name = "detailPane" + tmpId;
1502
+ newCol.options.label = "附件信息";
1503
+ let vabUploadCon = this.copyNewFieldWidget(
1504
+ this.getFieldWidgetByType("vabUpload")
1505
+ ); //vabUpload
1506
+ newCol.widgetList.push(vabUploadCon);
1507
+ newCon.panes.push(newCol);
1508
+
1509
+ /* 「详情模块(标签)」面板条目:type=detail-tabs + targetType=detail,落地后就是 detail,
1510
+ 不是新的容器类型。与「详情模块」的区别是内容模块不直接挂在正文区,而是收进标签里,
1511
+ 详见 docs/详情模块标签承载方案.md */
1512
+ if (newCon.sourceType === "detail-tabs") {
1513
+ // 上面已按 detail 的默认骨架建好一批内容模块,整体挪进第一个标签——
1514
+ // 标签形态下正文区只放标签容器,不留散在标签外面的模块。
1515
+ let presetPanes = newCon.panes.splice(0);
1516
+
1517
+ // 标签内的模块由 detail-plain 承载:它自带一套独立锚点导航,
1518
+ // 外层 baseTabs 探测不到标签内的模块(tab-item 不满足 getTabs 的两个条件)
1519
+ let plainCon = this.copyNewContainerWidget(
1520
+ this.getContainerByType("detail-plain")
1521
+ );
1522
+ plainCon.panes = presetPanes; // 丢掉 detail-plain 自带的默认模块,用上面建好的这批
1523
+ plainCon.options.hideNav = false; // schema 默认关导航,标签内要开
1524
+
1525
+ let tabCon = this.copyNewContainerWidget(
1526
+ this.getContainerByType("tab")
1527
+ );
1528
+ tabCon.tabs[0].widgetList.push(plainCon);
1529
+
1530
+ // copyNewContainerWidget 只预置 1 个 tab-pane,只有一个标签页的标签栏看着像 bug,补第二个
1531
+ let secondPane = baseRefUtil.deepClone(
1532
+ this.getContainerByType("tab-pane")
1533
+ );
1534
+ secondPane.id = "tab-pane-" + baseRefUtil.generateId();
1535
+ secondPane.options.name = "tab2";
1536
+ secondPane.options.label = "tab 2";
1537
+ tabCon.tabs.push(secondPane);
1538
+
1539
+ newCon.panes.push(tabCon);
1540
+ }
1541
+ } else if (newCon.type === "table-column") {
1542
+ newCon.options.label = "tableColumn";
1543
+ } else if (newCon.type === "h5-card") {
1544
+ let newCol = baseRefUtil.deepClone(
1545
+ this.getContainerByType("h5-card-pane")
1546
+ );
1547
+ let tmpId = baseRefUtil.generateId();
1548
+ newCol.id = "h5-card-pane-" + tmpId;
1549
+ newCol.options.name = "h5CardPane" + tmpId;
1550
+ newCol.options.label = "基本信息";
1551
+ newCon.panes.push(newCol);
1552
+ } else if (newCon.type === "detail-h5") {
1553
+ // 一张 h5-card:基础信息 / 明细信息 / 附件信息
1554
+ let newCard = this.copyNewContainerWidget(
1555
+ this.getContainerByType("h5-card")
1556
+ );
1557
+ newCon.panes.push(newCard);
1558
+
1559
+ // 基础信息:默认放 h5 表格(一行两列),对齐 PC 详情的「基础信息 + 表格」
1560
+ let basicPane = newCard.panes[0];
1561
+ if (basicPane) {
1562
+ basicPane.options.label = "基础信息";
1563
+ let h5Table = this.copyNewContainerWidget(
1564
+ this.getContainerByType("h5-table")
1565
+ );
1566
+ basicPane.widgetList.push(h5Table);
1567
+ }
1568
+
1569
+ // 明细信息:H5 列表;只读阶段不预置新增/查看按钮(点行仍可进详情)
1570
+ let newCardPane = this.copyNewContainerWidget(
1571
+ this.getContainerByType("h5-card-pane")
1572
+ );
1573
+ newCardPane.options.label = "明细信息";
1574
+ newCard.panes.push(newCardPane);
1575
+
1576
+ let listH5 = this.copyNewContainerWidget(
1577
+ this.getContainerByType("list-h5")
1578
+ );
1579
+ newCardPane.widgetList.push(listH5);
1580
+
1581
+ // 附件信息
1582
+ newCardPane = this.copyNewContainerWidget(
1583
+ this.getContainerByType("h5-card-pane")
1584
+ );
1585
+ newCardPane.options.label = "附件信息";
1586
+ newCard.panes.push(newCardPane);
1587
+
1588
+ let vabUploadCon = this.copyNewFieldWidget(
1589
+ this.getFieldWidgetByType("vabUpload")
1590
+ );
1591
+ newCardPane.widgetList.push(vabUploadCon);
1592
+ } else if (newCon.type === "h5-table") {
1593
+ /* 默认 4 行 × 2 列,对齐 H5「一行两个」的紧凑版式。
1594
+ 不再预置 input:H5 面板已下架单行输入,空单元格由设计者拖入字段。 */
1595
+ const h5TableCols = 2;
1596
+ const h5TableRows = 4;
1597
+ for (let i = 0; i < h5TableRows; i++) {
1598
+ let newRow = {
1599
+ cols: [],
1600
+ };
1601
+ newRow.id = "table-row-" + baseRefUtil.generateId();
1602
+ newRow.merged = false;
1603
+
1604
+ for (let j = 0; j < h5TableCols; j++) {
1605
+ let newCell = baseRefUtil.deepClone(
1606
+ this.getContainerByType("h5-table-cell")
1607
+ );
1608
+ newCell.id = "table-cell-" + baseRefUtil.generateId();
1609
+ newCell.options.name = newCell.id;
1610
+ newCell.merged = false;
1611
+ newCell.options.colspan = 1;
1612
+ newCell.options.rowspan = 1;
1613
+ newRow.cols.push(newCell);
1614
+ }
1615
+
1616
+ newCon.rows.push(newRow);
1617
+ }
1618
+ } else if (newCon.type === "tree-pane") {
1619
+ //初始化列表
1620
+ let dataTableCon = this.copyNewContainerWidget(
1621
+ this.getContainerByType("data-table")
1622
+ );
1623
+ dataTableCon.options.showPagination = true;
1624
+ dataTableCon.options.showSearchArea = true;
1625
+ dataTableCon.options.isQueryTable = true;
1626
+ dataTableCon.options.tableHeight = "auto";
1627
+ dataTableCon.options.accessReturnType = "2";
1628
+
1629
+ newCon.widgetList.push(dataTableCon);
1630
+
1631
+ let addButton = this.copyNewFieldWidget(
1632
+ this.getFieldWidgetByType("add_button")
1633
+ );
1634
+ addButton.options.onClick =
1635
+ "this.getWidgetRef('" +
1636
+ dataTableCon.options.name +
1637
+ "').openEditDialog();";
1638
+ dataTableCon.buttons.push(addButton);
1639
+
1640
+ let tableExportButton = this.copyNewFieldWidget(
1641
+ this.getFieldWidgetByType("table-export-button")
1642
+ );
1643
+ tableExportButton.options.tableExportParam =
1644
+ "return { title: '导出', targetRef: '" +
1645
+ dataTableCon.options.name +
1646
+ "'}";
1647
+ dataTableCon.buttons.push(tableExportButton);
1648
+
1649
+ // 两个查询条件的值由树节点点击注入,勾上「固定查询条件」后
1650
+ // 刷新、查询条件设置的还原/确定都不会把它清掉
1651
+ let searchInput = this.copyNewFieldWidget(
1652
+ this.getFieldWidgetByType("input")
1653
+ );
1654
+ searchInput.options.disabled = true;
1655
+ searchInput.options.fixedQuery = true;
1656
+ searchInput.options.label = newCon.options.treeLabel;
1657
+ dataTableCon.widgetList.push(searchInput);
1658
+
1659
+ let searchIdInput = this.copyNewFieldWidget(
1660
+ this.getFieldWidgetByType("input")
1661
+ );
1662
+ searchIdInput.options.disabled = true;
1663
+ searchIdInput.options.hidden = true;
1664
+ searchIdInput.options.fixedQuery = true;
1665
+ searchIdInput.options.label = `隐藏${newCon.options.treeLabel}ID`;
1666
+ dataTableCon.widgetList.push(searchIdInput);
1667
+
1668
+ // 存量表单没有 fixedQuery 开关,仍靠 ignoreFields 兜底刷新按钮;
1669
+ // 新建的表单两条通道并存(取并集),不冲突
1670
+ dataTableCon.options.onResetTable = `this.resetEvent({\n ignoreFields:['${searchInput.options.name}', '${searchIdInput.options.name}']\n});`;
1671
+
1672
+ //初始化树
1673
+ let treeCon = this.copyNewContainerWidget(
1674
+ this.getContainerByType("tree")
1675
+ );
1676
+ treeCon.options.onNodeClick = `this.getWidgetRef('${searchInput.options.name}').setValue(data.label);\nthis.getWidgetRef('${searchIdInput.options.name}').setValue(data.id);\nthis.getWidgetRef('${dataTableCon.options.name}').searchEvent();`;
1677
+
1678
+ newCon.options.onTreeLabelClick = `this.getWidgetRef('${treeCon.options.name}').setCurrentKey();\nthis.getWidgetRef('${searchInput.options.name}').setValue(null);\nthis.getWidgetRef('${searchIdInput.options.name}').setValue(null);\nthis.getWidgetRef('${dataTableCon.options.name}').searchEvent();`;
1679
+ newCon.leftWidgetList.push(treeCon);
1680
+ }
1681
+ //newCon.options.customClass = []
1682
+
1683
+ delete newCon.displayName;
1684
+ return newCon;
1685
+ },
1686
+
1687
+ addContainerByDbClick(container) {
1688
+ let newCon = this.copyNewContainerWidget(container);
1689
+ this.widgetList.push(newCon);
1690
+ this.setSelected(newCon);
1691
+ },
1692
+
1693
+ addFieldByDbClick(widget) {
1694
+ let newWidget = this.copyNewFieldWidget(widget);
1695
+ if (!!this.selectedWidget && this.selectedWidget.type === "tab") {
1696
+ //获取当前激活的tabPane
1697
+ let activeTab = this.selectedWidget.tabs[0];
1698
+ this.selectedWidget.tabs.forEach((tabPane) => {
1699
+ if (!!tabPane.options.active) {
1700
+ activeTab = tabPane;
1701
+ }
1702
+ });
1703
+
1704
+ !!activeTab && activeTab.widgetList.push(newWidget);
1705
+ } else if (!!this.selectedWidget && !!this.selectedWidget.widgetList) {
1706
+ this.selectedWidget.widgetList.push(newWidget);
1707
+ } else {
1708
+ this.widgetList.push(newWidget);
1709
+ }
1710
+
1711
+ this.setSelected(newWidget);
1712
+ this.emitEvent("canvas-add-field", newWidget.options.name),
1713
+ this.emitHistoryChange();
1714
+ },
1715
+ /**
1716
+ * 删除详情容器下的一个 pane
1717
+ * @param gridWidget 详情容器(detail / detail-plain)
1718
+ * @param paneOrIdx pane 的 widget 引用,或它在 panes 中的下标。
1719
+ * detail 的属性面板按 type 做了显隐,下标不再可靠,故走引用;
1720
+ * detail-plain 的属性面板仍传下标,这里一并兼容。
1721
+ */
1722
+ deletePaneOfDetail(gridWidget, paneOrIdx) {
1723
+ if (!gridWidget || !gridWidget.panes) return;
1724
+ let isIdx = typeof paneOrIdx === "number";
1725
+ let colIdx = isIdx ? paneOrIdx : gridWidget.panes.indexOf(paneOrIdx);
1726
+ if (colIdx < 0) return;
1727
+ gridWidget.panes.splice(colIdx, 1);
1728
+ },
1729
+ cloneDetailPane(widget, parentWidget) {
1730
+ let newGridCol = baseRefUtil.deepClone(
1731
+ this.getContainerByType("detail-pane")
1732
+ );
1733
+ let tmpId = baseRefUtil.generateId();
1734
+ newGridCol.id = "detail-pane-" + tmpId;
1735
+ newGridCol.options.name = "detailPane" + tmpId;
1736
+ newGridCol.options.label = widget.options.label;
1737
+ parentWidget.panes.push(newGridCol);
1738
+ },
1739
+ cloneH5CardPanePane(widget, parentWidget) {
1740
+ let newGridCol = baseRefUtil.deepClone(
1741
+ this.getContainerByType("h5-card-pane")
1742
+ );
1743
+ let tmpId = baseRefUtil.generateId();
1744
+ newGridCol.id = "h5-card-pane-" + tmpId;
1745
+ newGridCol.options.name = "h5CardPane" + tmpId;
1746
+ newGridCol.options.label = widget.options.label;
1747
+ parentWidget.panes.push(newGridCol);
1748
+ },
1749
+
1750
+ addNewPaneOfDetail(gridWidget) {
1751
+ const cols = gridWidget.panes;
1752
+ let newGridCol = baseRefUtil.deepClone(
1753
+ this.getContainerByType("detail-pane")
1754
+ );
1755
+ let tmpId = baseRefUtil.generateId();
1756
+ newGridCol.id = "detail-pane-" + tmpId;
1757
+ newGridCol.options.name = "detailPane" + tmpId;
1758
+ newGridCol.options.label = "detailPane" + tmpId;
1759
+ // 默认添加一个栅格控件到新 pane 的 widgetList 中,含3列平均分布
1760
+ let defaultGrid = baseRefUtil.deepClone(
1761
+ this.getContainerByType("grid")
1762
+ );
1763
+ defaultGrid.id = "grid-" + baseRefUtil.generateId();
1764
+ // 添加3列,每列 span=8(24栏栅格均分)
1765
+ for (let i = 0; i < 3; i++) {
1766
+ let col = baseRefUtil.deepClone(
1767
+ this.getContainerByType("grid-col")
1768
+ );
1769
+ col.id = "grid-col-" + baseRefUtil.generateId();
1770
+ col.options.span = 8;
1771
+ defaultGrid.cols.push(col);
1772
+ }
1773
+ newGridCol.widgetList.push(defaultGrid);
1774
+ gridWidget.panes.push(newGridCol);
1775
+ },
1776
+
1777
+ deleteColOfGrid(gridWidget, colIdx) {
1778
+ if (!!gridWidget && !!gridWidget.cols) {
1779
+ gridWidget.cols.splice(colIdx, 1);
1780
+ }
1781
+ },
1782
+
1783
+ addNewColOfGrid(gridWidget) {
1784
+ const cols = gridWidget.cols;
1785
+ let newGridCol = baseRefUtil.deepClone(
1786
+ this.getContainerByType("grid-col")
1787
+ );
1788
+ let tmpId = baseRefUtil.generateId();
1789
+ newGridCol.id = "grid-col-" + tmpId;
1790
+ newGridCol.options.name = "gridCol" + tmpId;
1791
+ if (!!cols && cols.length > 0) {
1792
+ let spanSum = 0;
1793
+ cols.forEach((col) => {
1794
+ spanSum += col.options.span;
1795
+ });
1796
+
1797
+ if (spanSum >= 24) {
1798
+ //this.$message.info('列栅格之和超出24')
1799
+ console.log("列栅格之和超出24");
1800
+ gridWidget.cols.push(newGridCol);
1801
+ } else {
1802
+ newGridCol.options.span = 24 - spanSum > 12 ? 12 : 24 - spanSum;
1803
+ gridWidget.cols.push(newGridCol);
1804
+ }
1805
+ } else {
1806
+ gridWidget.cols = [newGridCol];
1807
+ }
1808
+ },
1809
+
1810
+ addTabPaneOfTabs(tabsWidget) {
1811
+ const tabPanes = tabsWidget.tabs;
1812
+ let newTabPane = baseRefUtil.deepClone(
1813
+ this.getContainerByType("tab-pane")
1814
+ );
1815
+ newTabPane.id = "tab-pane-" + baseRefUtil.generateId();
1816
+ newTabPane.options.name = newTabPane.id;
1817
+ newTabPane.options.label = "tab " + (tabPanes.length + 1);
1818
+ tabPanes.push(newTabPane);
1819
+ },
1820
+
1821
+ deleteTabPaneOfTabs(tabsWidget, tpIdx) {
1822
+ tabsWidget.tabs.splice(tpIdx, 1);
1823
+ },
1824
+
1825
+ addDropdownItem(tabsWidget) {
1826
+ const tabPanes = tabsWidget.widgetList;
1827
+ let newTabPane = baseRefUtil.deepClone(
1828
+ this.getFieldWidgetByType("dropdown-item")
1829
+ );
1830
+ newTabPane.id = "dropdown-item-" + baseRefUtil.generateId();
1831
+ newTabPane.options.name = newTabPane.id;
1832
+ newTabPane.options.label = "dropdown-item " + (tabPanes.length + 1);
1833
+ tabPanes.push(newTabPane);
1834
+ },
1835
+
1836
+ deleteDropdownItem(tabsWidget, tpIdx) {
1837
+ tabsWidget.widgetList.splice(tpIdx, 1);
1838
+ },
1839
+
1840
+ emitEvent(evtName, evtData) {
1841
+ //用于兄弟组件发射事件
1842
+ this.vueInstance.$emit(evtName, evtData);
1843
+ },
1844
+
1845
+ handleEvent(evtName, callback) {
1846
+ //用于兄弟组件接收事件
1847
+ this.vueInstance.$on(evtName, (data) => callback(data));
1848
+ },
1849
+
1850
+ setCssClassList(cssClassList) {
1851
+ this.cssClassList = cssClassList;
1852
+ },
1853
+
1854
+ getCssClassList() {
1855
+ return this.cssClassList;
1856
+ },
1857
+
1858
+ registerFormWidget(formWidget) {
1859
+ this.formWidget = formWidget;
1860
+ },
1861
+
1862
+ initHistoryData() {
1863
+ this.loadFormContentFromStorage();
1864
+ this.historyData.index++;
1865
+ this.historyData.steps[this.historyData.index] = {
1866
+ widgetList: baseRefUtil.deepClone(this.widgetList),
1867
+ formConfig: baseRefUtil.deepClone(this.formConfig),
1868
+ };
1869
+ },
1870
+
1871
+ emitHistoryChange() {
1872
+ //console.log('------------', 'Form history changed!')
1873
+
1874
+ if (this.historyData.index === this.historyData.maxStep - 1) {
1875
+ this.historyData.steps.shift();
1876
+ } else {
1877
+ this.historyData.index++;
1878
+ }
1879
+
1880
+ this.historyData.steps[this.historyData.index] = {
1881
+ widgetList: baseRefUtil.deepClone(this.widgetList),
1882
+ formConfig: baseRefUtil.deepClone(this.formConfig),
1883
+ };
1884
+
1885
+ this.saveFormContentToStorage();
1886
+
1887
+ if (this.historyData.index < this.historyData.steps.length - 1) {
1888
+ this.historyData.steps = this.historyData.steps.slice(
1889
+ 0,
1890
+ this.historyData.index + 1
1891
+ );
1892
+ }
1893
+
1894
+ //console.log('history', this.historyData.index)
1895
+ },
1896
+
1897
+ saveCurrentHistoryStep() {
1898
+ this.historyData.steps[this.historyData.index] = baseRefUtil.deepClone({
1899
+ widgetList: this.widgetList,
1900
+ formConfig: this.formConfig,
1901
+ });
1902
+
1903
+ this.saveFormContentToStorage();
1904
+ },
1905
+
1906
+ undoHistoryStep() {
1907
+ if (this.historyData.index !== 0) {
1908
+ this.historyData.index--;
1909
+ }
1910
+ //console.log('undo', this.historyData.index)
1911
+
1912
+ this.widgetList = baseRefUtil.deepClone(
1913
+ this.historyData.steps[this.historyData.index].widgetList
1914
+ );
1915
+ this.formConfig = baseRefUtil.deepClone(
1916
+ this.historyData.steps[this.historyData.index].formConfig
1917
+ );
1918
+ },
1919
+
1920
+ redoHistoryStep() {
1921
+ if (this.historyData.index !== this.historyData.steps.length - 1) {
1922
+ this.historyData.index++;
1923
+ }
1924
+ //console.log('redo', this.historyData.index)
1925
+
1926
+ this.widgetList = baseRefUtil.deepClone(
1927
+ this.historyData.steps[this.historyData.index].widgetList
1928
+ );
1929
+ this.formConfig = baseRefUtil.deepClone(
1930
+ this.historyData.steps[this.historyData.index].formConfig
1931
+ );
1932
+ },
1933
+
1934
+ undoEnabled() {
1935
+ return this.historyData.index > 0 && this.historyData.steps.length > 0;
1936
+ },
1937
+
1938
+ redoEnabled() {
1939
+ return this.historyData.index < this.historyData.steps.length - 1;
1940
+ },
1941
+
1942
+ saveFormContentToStorage() {
1943
+ window.localStorage.setItem(
1944
+ "widget__list__backup",
1945
+ JSON.stringify(this.widgetList)
1946
+ );
1947
+ window.localStorage.setItem(
1948
+ "form__config__backup",
1949
+ JSON.stringify(this.formConfig)
1950
+ );
1951
+ },
1952
+
1953
+ loadFormContentFromStorage() {
1954
+ let widgetListBackup = window.localStorage.getItem(
1955
+ "widget__list__backup"
1956
+ );
1957
+ if (!!widgetListBackup) {
1958
+ this.widgetList = JSON.parse(widgetListBackup);
1959
+ }
1960
+
1961
+ let formConfigBackup = window.localStorage.getItem(
1962
+ "form__config__backup"
1963
+ );
1964
+ if (!!formConfigBackup) {
1965
+ //this.formConfig = JSON.parse(formConfigBackup)
1966
+ baseRefUtil.overwriteObj(
1967
+ this.formConfig,
1968
+ JSON.parse(formConfigBackup)
1969
+ ); /* 用=赋值,会导致inject依赖注入的formConfig属性变成非响应式 */
1970
+ }
1971
+ },
1972
+ getColumnWidget(row, isEdit) {
1973
+ //获取
1974
+ let formatS = isEdit ? row.editFormatS : row.formatS;
1975
+ let type = columnFormatMap[formatS];
1976
+ if (!type) return null;
1977
+ if (isEdit) {
1978
+ if (row.editWidget) {
1979
+ return row.editWidget;
1980
+ }
1981
+ if (row.editColumnOption) {
1982
+ let fieldWidget = this.copyNewFieldWidget(
1983
+ this.getFieldWidgetByType(type)
1984
+ );
1985
+ fieldWidget.options = row.editColumnOption;
1986
+ return fieldWidget;
1987
+ }
1988
+ } else {
1989
+ if (row.widget) {
1990
+ return row.widget;
1991
+ }
1992
+ if (row.columnOption) {
1993
+ let fieldWidget = this.copyNewFieldWidget(
1994
+ this.getFieldWidgetByType(type)
1995
+ );
1996
+ fieldWidget.options = row.columnOption;
1997
+ return fieldWidget;
1998
+ }
1999
+ }
2000
+ return this.createColumnWidget(row, isEdit);
2001
+ },
2002
+ getIsFileWidget(type) {
2003
+ return type === "vabUpload" || type === "baseAttachment";
2004
+ },
2005
+ createColumnWidget(row, isEdit) {
2006
+ let formatS = isEdit ? row.editFormatS : row.formatS;
2007
+ let type = columnFormatMap[formatS];
2008
+ if (!type) return null;
2009
+
2010
+ let columnSelectedWidget = null;
2011
+ if (type) {
2012
+ columnSelectedWidget = this.copyNewFieldWidget(
2013
+ this.getFieldWidgetByType(type)
2014
+ );
2015
+
2016
+ if (columnSelectedWidget.options.hasOwnProperty("required")) {
2017
+ columnSelectedWidget.options.required = row.required || false;
2018
+ }
2019
+
2020
+ if ("editDelete" === formatS) {
2021
+ columnSelectedWidget.options.prefixIcon = "el-icon-delete";
2022
+ columnSelectedWidget.options.label = "删除";
2023
+ columnSelectedWidget.options.labelHidden = true;
2024
+ columnSelectedWidget.options.hiddenByWf = true;
2025
+ columnSelectedWidget.options.onClick =
2026
+ "let tableParam = this.tableParam;\nlet tableRef = this.getWidgetRef(this.parentWidget.options.name);\ntableRef.deleteRow(tableParam.row,tableParam.rowIndex);";
2027
+ } else if ("editButton" === formatS) {
2028
+ columnSelectedWidget.options.prefixIcon = "el-icon-edit";
2029
+ columnSelectedWidget.options.label = "查看";
2030
+ columnSelectedWidget.options.labelHidden = true;
2031
+ columnSelectedWidget.options.onClick =
2032
+ "let tableParam = this.tableParam;\nlet tableRef = this.getWidgetRef(this.parentWidget.options.name);\ntableRef.openEditDialog(tableParam.row)";
2033
+ } else if ("addSiblingEditRow" === formatS) {
2034
+ columnSelectedWidget.options.prefixIcon = "el-icon-plus";
2035
+ columnSelectedWidget.options.label = "新增兄弟节点";
2036
+ columnSelectedWidget.options.labelHidden = false;
2037
+ columnSelectedWidget.options.onClick =
2038
+ "let tableParam = this.tableParam;\nthis.getParentTarget().addSiblingTreeRow(null,tableParam);";
2039
+ } else if ("addChildTreeRow" === formatS) {
2040
+ columnSelectedWidget.options.prefixIcon = "el-icon-plus";
2041
+ columnSelectedWidget.options.label = "新增子节点";
2042
+ columnSelectedWidget.options.labelHidden = false;
2043
+ columnSelectedWidget.options.onClick =
2044
+ "let tableParam = this.tableParam;\nthis.getParentTarget().addChildTreeRow(null,tableParam);";
2045
+ } else if ("moveUpRow" === formatS) {
2046
+ columnSelectedWidget.options.label = "↑上移";
2047
+ columnSelectedWidget.options.labelHidden = false;
2048
+ columnSelectedWidget.options.onClick =
2049
+ "let tableParam = this.tableParam;\nthis.getParentTarget().moveUpRow(tableParam);";
2050
+ } else if ("moveDownRow" === formatS) {
2051
+ columnSelectedWidget.options.label = "↓下移";
2052
+ columnSelectedWidget.options.labelHidden = false;
2053
+ columnSelectedWidget.options.onClick =
2054
+ "let tableParam = this.tableParam;\nthis.getParentTarget().moveDownRow(tableParam);";
2055
+ } else if ("removeTreeRow" === formatS) {
2056
+ columnSelectedWidget.options.prefixIcon = "el-icon-delete";
2057
+ columnSelectedWidget.options.label = "删除";
2058
+ columnSelectedWidget.options.labelHidden = true;
2059
+ columnSelectedWidget.options.onClick =
2060
+ "let tableParam = this.tableParam;\nthis.getParentTarget().removeTreeRow(tableParam);";
2061
+ }
2062
+
2063
+ if (columnSelectedWidget.options.hasOwnProperty("keyName")) {
2064
+ if (!this.getIsFileWidget(type)) {
2065
+ columnSelectedWidget.options.keyName = row.prop;
2066
+ }
2067
+
2068
+ columnSelectedWidget.options.keyNameEnabled = true;
2069
+ } else {
2070
+ columnSelectedWidget.options.name = row.prop;
2071
+ }
2072
+
2073
+ if (type === "dropdown") {
2074
+ columnSelectedWidget.options.dropdownType = "link";
2075
+ } else if (type !== "button" && type !== "a-link") {
2076
+ columnSelectedWidget.options.label = row.label;
2077
+ columnSelectedWidget.options.labelHidden = true;
2078
+ }
2079
+ }
2080
+ return columnSelectedWidget;
2081
+ },
2082
+ };
2083
+ };
2084
+ })();
2085
+
2086
+ export const createDesigner = createDesigner0;