@houaoran/designer 1.0.0

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 (126) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +98 -0
  3. package/dist/components.es.js +11424 -0
  4. package/dist/components.umd.js +878 -0
  5. package/dist/index.es.js +39113 -0
  6. package/dist/index.umd.js +1187 -0
  7. package/package.json +96 -0
  8. package/src/components/DragBox.vue +49 -0
  9. package/src/components/DragTool.vue +235 -0
  10. package/src/components/EventConfig.vue +557 -0
  11. package/src/components/FcDesigner.vue +2569 -0
  12. package/src/components/FcTitle.vue +69 -0
  13. package/src/components/FetchConfig.vue +415 -0
  14. package/src/components/FieldInput.vue +371 -0
  15. package/src/components/FnConfig.vue +315 -0
  16. package/src/components/FnEditor.vue +327 -0
  17. package/src/components/FnInput.vue +103 -0
  18. package/src/components/FormLabel.vue +47 -0
  19. package/src/components/HtmlEditor.vue +125 -0
  20. package/src/components/JsonPreview.vue +146 -0
  21. package/src/components/OptionsTextInput.vue +151 -0
  22. package/src/components/PropsInput.vue +72 -0
  23. package/src/components/Required.vue +75 -0
  24. package/src/components/Row.vue +26 -0
  25. package/src/components/SignaturePad.vue +176 -0
  26. package/src/components/Struct.vue +153 -0
  27. package/src/components/StructEditor.vue +121 -0
  28. package/src/components/StructTree.vue +209 -0
  29. package/src/components/TableOptions.vue +164 -0
  30. package/src/components/TreeOptions.vue +167 -0
  31. package/src/components/TypeSelect.vue +144 -0
  32. package/src/components/Validate.vue +302 -0
  33. package/src/components/ValueInput.vue +89 -0
  34. package/src/components/Warning.vue +46 -0
  35. package/src/components/ai/AiPanel.vue +1122 -0
  36. package/src/components/ai/MarkdownRenderer.vue +548 -0
  37. package/src/components/language/LanguageConfig.vue +174 -0
  38. package/src/components/language/LanguageInput.vue +191 -0
  39. package/src/components/style/BackgroundInput.vue +315 -0
  40. package/src/components/style/BorderInput.vue +242 -0
  41. package/src/components/style/BoxSizeInput.vue +166 -0
  42. package/src/components/style/BoxSpaceInput.vue +269 -0
  43. package/src/components/style/ColorInput.vue +90 -0
  44. package/src/components/style/ConfigItem.vue +118 -0
  45. package/src/components/style/FontInput.vue +197 -0
  46. package/src/components/style/PositionInput.vue +146 -0
  47. package/src/components/style/RadiusInput.vue +164 -0
  48. package/src/components/style/ShadowContent.vue +335 -0
  49. package/src/components/style/ShadowInput.vue +91 -0
  50. package/src/components/style/SizeInput.vue +118 -0
  51. package/src/components/style/StyleConfig.vue +307 -0
  52. package/src/components/table/Table.vue +252 -0
  53. package/src/components/table/TableView.vue +1058 -0
  54. package/src/components/tableForm/TableForm.vue +471 -0
  55. package/src/components/tableForm/TableFormColumnView.vue +103 -0
  56. package/src/components/tableForm/TableFormView.vue +46 -0
  57. package/src/components/tree/FcTree.vue +713 -0
  58. package/src/components/tree/FcTreeNode.vue +216 -0
  59. package/src/config/base/field.js +43 -0
  60. package/src/config/base/form.js +132 -0
  61. package/src/config/base/style.js +26 -0
  62. package/src/config/base/validate.js +15 -0
  63. package/src/config/index.js +70 -0
  64. package/src/config/menu.js +24 -0
  65. package/src/config/rule/alert.js +45 -0
  66. package/src/config/rule/button.js +49 -0
  67. package/src/config/rule/card.js +40 -0
  68. package/src/config/rule/cascader.js +121 -0
  69. package/src/config/rule/checkbox.js +68 -0
  70. package/src/config/rule/col.js +86 -0
  71. package/src/config/rule/collapse.js +30 -0
  72. package/src/config/rule/collapseItem.js +36 -0
  73. package/src/config/rule/color.js +53 -0
  74. package/src/config/rule/date.js +66 -0
  75. package/src/config/rule/dateRange.js +60 -0
  76. package/src/config/rule/divider.js +31 -0
  77. package/src/config/rule/editor.js +31 -0
  78. package/src/config/rule/group.js +86 -0
  79. package/src/config/rule/html.js +43 -0
  80. package/src/config/rule/image.js +32 -0
  81. package/src/config/rule/input.js +62 -0
  82. package/src/config/rule/number.js +49 -0
  83. package/src/config/rule/password.js +52 -0
  84. package/src/config/rule/radio.js +43 -0
  85. package/src/config/rule/rate.js +44 -0
  86. package/src/config/rule/row.js +46 -0
  87. package/src/config/rule/select.js +70 -0
  88. package/src/config/rule/signaturePad.js +59 -0
  89. package/src/config/rule/slider.js +53 -0
  90. package/src/config/rule/space.js +44 -0
  91. package/src/config/rule/subForm.js +47 -0
  92. package/src/config/rule/switch.js +46 -0
  93. package/src/config/rule/tabPane.js +29 -0
  94. package/src/config/rule/table.js +37 -0
  95. package/src/config/rule/tableForm.js +115 -0
  96. package/src/config/rule/tableFormColumn.js +55 -0
  97. package/src/config/rule/tabs.js +38 -0
  98. package/src/config/rule/tag.js +69 -0
  99. package/src/config/rule/text.js +41 -0
  100. package/src/config/rule/textarea.js +63 -0
  101. package/src/config/rule/time.js +58 -0
  102. package/src/config/rule/timeRange.js +49 -0
  103. package/src/config/rule/title.js +37 -0
  104. package/src/config/rule/transfer.js +59 -0
  105. package/src/config/rule/tree.js +70 -0
  106. package/src/config/rule/treeSelect.js +77 -0
  107. package/src/config/rule/upload.js +107 -0
  108. package/src/form/index.js +19 -0
  109. package/src/index.js +173 -0
  110. package/src/locale/en.js +981 -0
  111. package/src/locale/zh-cn.js +983 -0
  112. package/src/style/fonts/fc-icons.woff +0 -0
  113. package/src/style/icon.css +1052 -0
  114. package/src/style/index.css +836 -0
  115. package/src/utils/form.js +9 -0
  116. package/src/utils/highlight/highlight.min.js +307 -0
  117. package/src/utils/highlight/javascript.min.js +80 -0
  118. package/src/utils/highlight/style.css +1 -0
  119. package/src/utils/highlight/xml.min.js +29 -0
  120. package/src/utils/hintStubs.js +120 -0
  121. package/src/utils/index.js +544 -0
  122. package/src/utils/jsonDiff.js +173 -0
  123. package/src/utils/locale.js +23 -0
  124. package/src/utils/message.js +19 -0
  125. package/src/utils/template.js +105 -0
  126. package/types/index.d.ts +575 -0
@@ -0,0 +1,1058 @@
1
+ <template>
2
+ <div class="_fd-table-view" :class="{ 'is-mini': mini, 'is-table-form': formStyle }">
3
+ <table border="1" cellspacing="0" cellpadding="0" :style="tableColor" @mouseleave="mouseup" @mouseup="mouseup">
4
+ <template v-for="(_, pid) in rule.row" :key="pid">
5
+ <tr>
6
+ <template v-for="(_, idx) in rule.col">
7
+ <td
8
+ v-if="lattice[pid][idx].show"
9
+ :key="`${pid}${idx}`"
10
+ :ref="`td_${pid}:${idx}`"
11
+ class="_fd-table-view-cell"
12
+ v-bind="lattice[pid][idx] ? { colspan: lattice[pid][idx].colspan, rowspan: lattice[pid][idx].rowspan } : {}"
13
+ :style="[tableColor, (style && style[`${pid}:${idx}`]) || {}]"
14
+ :class="[
15
+ (rule.class && rule.class[`${pid}:${idx}`]) || '',
16
+ { selected: selection.indexOf(`${pid}:${idx}`) > -1 },
17
+ ]"
18
+ @contextmenu="contextmenu($event, { pid, idx })"
19
+ @mousedown="mousedown($event, { pid, idx })"
20
+ @mousemove="mousemove($event, { pid, idx })"
21
+ @dblclick="dblclick($event, { pid, idx })"
22
+ >
23
+ <div
24
+ class="_fd-table-row-handle"
25
+ v-if="pid !== rule.row - 1"
26
+ @mousedown="rowResize($event, { pid, idx })"
27
+ ></div>
28
+ <div
29
+ class="_fd-table-col-handle"
30
+ v-if="idx !== rule.col - 1"
31
+ @mousedown="colResize($event, { pid, idx })"
32
+ ></div>
33
+ <DragTool :drag-btn="false" :handle-btn="true" @active="active({ pid, idx })" :unique="lattice[pid][idx].id">
34
+ <DragBox
35
+ v-bind="dragProp"
36
+ @add="e => dragAdd(e, { pid, idx })"
37
+ :ref="'drag' + pid + idx"
38
+ @end="e => dragEnd(e, { pid, idx })"
39
+ @start="e => dragStart(e)"
40
+ @unchoose="e => dragUnchoose(e)"
41
+ :list="getSlotChildren([`${pid}:${idx}`, ...lattice[pid][idx].slot])"
42
+ >
43
+ <slot :name="`${pid}:${idx}`"></slot>
44
+ </DragBox>
45
+ <template #handle>
46
+ <div
47
+ class="_fd-drag-btn _fd-table-view-btn"
48
+ @click.stop="addRow({ pid, idx, data: lattice[pid][idx] }, 0)"
49
+ >
50
+ <i class="fc-icon icon-add-col"></i>
51
+ </div>
52
+ <div
53
+ class="_fd-drag-btn _fd-table-view-btn"
54
+ @click.stop="addCol({ pid, idx, data: lattice[pid][idx] }, 0)"
55
+ >
56
+ <i class="fc-icon icon-add-col" style="transform: rotate(90deg)"></i>
57
+ </div>
58
+ </template>
59
+ </DragTool>
60
+ </td>
61
+ </template>
62
+ </tr>
63
+ </template>
64
+ </table>
65
+ <div ref="contextMenu" class="_fd-table-context-menu" v-if="visible" :style="menuPos">
66
+ <div class="_fd-table-context-menuitem" @click.stop="selectionStyle">{{ t('props.style') }}</div>
67
+ <div class="_fd-table-context-menuitem" @click.stop="rmSelectionContent">{{ t('props.clear') }}</div>
68
+ <div class="_fd-table-context-menu-separator"></div>
69
+ <div class="_fd-table-context-menuitem" @click.stop="mergeSelection(false)">{{ t('tableOptions.batchMerge') }}</div>
70
+ <div class="_fd-table-context-menuitem" @click.stop="mergeSelection(true)">{{ t('tableOptions.batchSplit') }}</div>
71
+ <div class="_fd-table-context-menuitem" @click.stop="addCol({ pid: selectionPos.startRow, idx: selectionPos.startCol }, 1)">
72
+ {{ t('tableOptions.addLeft') }}
73
+ </div>
74
+ <div class="_fd-table-context-menuitem" @click.stop="addCol({ pid: selectionPos.startRow, idx: selectionPos.endCol }, 0)">
75
+ {{ t('tableOptions.addRight') }}
76
+ </div>
77
+ <div class="_fd-table-context-menuitem" @click.stop="addRow({ pid: selectionPos.startRow, idx: selectionPos.startCol }, 1)">
78
+ {{ t('tableOptions.addTop') }}
79
+ </div>
80
+ <div class="_fd-table-context-menuitem" @click.stop="addRow({ pid: selectionPos.startRow, idx: selectionPos.endCol }, 0)">
81
+ {{ t('tableOptions.addBottom') }}
82
+ </div>
83
+ <div class="_fd-table-context-menu-separator"></div>
84
+ <div class="_fd-table-context-menuitem" @click.stop="rmSelectionRow">{{ t('tableOptions.batchRmRow') }}</div>
85
+ <div class="_fd-table-context-menuitem" @click.stop="rmSelectionCol">{{ t('tableOptions.batchRmCol') }}</div>
86
+ </div>
87
+ </div>
88
+ </template>
89
+
90
+ <script>
91
+ import DragTool from '../DragTool.vue';
92
+ import DragBox from '../DragBox.vue';
93
+ import {defineComponent, nextTick} from 'vue';
94
+ import uniqueId from '@form-create/utils/lib/unique';
95
+
96
+ export default defineComponent({
97
+ name: 'FcTableView',
98
+ props: {
99
+ mini: Boolean,
100
+ formStyle: Boolean,
101
+ label: String,
102
+ width: [Number, String],
103
+ formCreateInject: Object,
104
+ border: {
105
+ type: Boolean,
106
+ default: true,
107
+ },
108
+ borderWidth: String,
109
+ borderColor: String,
110
+ rule: {
111
+ type: Object,
112
+ default: () => ({row: 1, col: 1}),
113
+ },
114
+ },
115
+ inject: ['designer'],
116
+ components: {
117
+ DragTool,
118
+ DragBox,
119
+ },
120
+ watch: {
121
+ rule: {
122
+ handler() {
123
+ this.initRule();
124
+ this.style = this.rule.style;
125
+ },
126
+ immediate: true,
127
+ },
128
+ },
129
+ data() {
130
+ return {
131
+ unique: {},
132
+ style: {},
133
+ selection: [],
134
+ selectionPos: null,
135
+ visible: false,
136
+ resize: {
137
+ isResizing: false,
138
+ startX: 0,
139
+ startY: 0,
140
+ startWidth: 0,
141
+ startHeight: 0,
142
+ },
143
+ menuPos: {
144
+ left: 0,
145
+ top: 0,
146
+ },
147
+ isSelecting: null,
148
+ oldSelection: null,
149
+ dragProp: {
150
+ rule: {
151
+ props: {
152
+ tag: 'el-col',
153
+ group: {
154
+ name: 'default',
155
+ put: (to, ...args) => {
156
+ to.el.__rule__ = this.formCreateInject.rule;
157
+ return this.designer.setupState.dragPut(to, ...args);
158
+ },
159
+ },
160
+ ghostClass: 'ghost',
161
+ animation: 150,
162
+ handle: '._fd-drag-btn',
163
+ emptyInsertThreshold: 0,
164
+ direction: 'vertical',
165
+ itemKey: 'type',
166
+ },
167
+ },
168
+ tag: 'tableCell',
169
+ },
170
+ lattice: {},
171
+ uni: {},
172
+ };
173
+ },
174
+ computed: {
175
+ t() {
176
+ return this.designer.setupState.t;
177
+ },
178
+ tableColor() {
179
+ const border = {};
180
+ if (this.border === false) {
181
+ border['border'] = '0 none';
182
+ } else {
183
+ if (this.borderColor) {
184
+ border['borderColor'] = this.borderColor;
185
+ }
186
+ if (this.borderWidth) {
187
+ border['borderWidth'] = this.borderWidth;
188
+ }
189
+ }
190
+ return border;
191
+ },
192
+ },
193
+ methods: {
194
+ async contextmenu(e) {
195
+ e.preventDefault();
196
+ e.stopPropagation();
197
+ if (this.selectionPos) {
198
+ this.visible = true;
199
+ await nextTick();
200
+ this.updateMenuPos(e.clientX, e.clientY);
201
+ }
202
+ },
203
+ updateMenuPos(x, y) {
204
+ const menu = this.$refs.contextMenu;
205
+ const menuWidth = menu?.offsetWidth || 0;
206
+ const menuHeight = menu?.offsetHeight || 0;
207
+ const edge = 8;
208
+ const viewportWidth = window.innerWidth;
209
+ const viewportHeight = window.innerHeight;
210
+
211
+ let left = x;
212
+ let top = y;
213
+
214
+ if (left + menuWidth + edge > viewportWidth) {
215
+ left = viewportWidth - menuWidth - edge;
216
+ }
217
+ if (left < edge) {
218
+ left = edge;
219
+ }
220
+ if (top + menuHeight + edge > viewportHeight) {
221
+ top = y - menuHeight;
222
+ }
223
+ if (top + menuHeight + edge > viewportHeight) {
224
+ top = viewportHeight - menuHeight - edge;
225
+ }
226
+ if (top < edge) {
227
+ top = edge;
228
+ }
229
+
230
+ this.menuPos = {
231
+ left: `${left}px`,
232
+ top: `${top}px`,
233
+ };
234
+ },
235
+ rowResize(e, {pid, idx}) {
236
+ e.preventDefault();
237
+ e.stopPropagation();
238
+ let height;
239
+ let key = `${this.lattice[pid][idx].startRow || pid}:${this.lattice[pid][idx].startCol || 0}`;
240
+ if (!this.$refs[`td_${key}`] || this.lattice[pid][idx].colspan > 1 || this.lattice[pid][idx].rowspan > 1) {
241
+ key = `${pid}:${idx}`;
242
+ }
243
+ const currentResizeElement = this.$refs[`td_${key}`][0].parentElement;
244
+ const style = this.rule.style[key] || {};
245
+
246
+ const doRowResize = e => {
247
+ if (!this.resize.isResizing) return;
248
+
249
+ const dy = e.clientY - this.resize.startY;
250
+ const newHeight = this.resize.startHeight + dy;
251
+ if (newHeight > 20) {
252
+ currentResizeElement.style.height = `${newHeight}px`;
253
+ height = newHeight;
254
+ }
255
+ };
256
+
257
+ const stopResize = () => {
258
+ if (!this.resize.isResizing) return;
259
+
260
+ this.resize.isResizing = false;
261
+
262
+ style.height = `${height}px`;
263
+
264
+ this.rule.style[key] = style;
265
+
266
+ document.removeEventListener('mousemove', doRowResize);
267
+ document.removeEventListener('mouseup', stopResize);
268
+ };
269
+ this.resize.isResizing = true;
270
+ this.resize.startY = e.clientY;
271
+ this.resize.startHeight = currentResizeElement.offsetHeight;
272
+ if (style.height) {
273
+ currentResizeElement.style.height = style.height;
274
+ delete style.height;
275
+ }
276
+
277
+ document.addEventListener('mousemove', doRowResize);
278
+ document.addEventListener('mouseup', stopResize);
279
+ },
280
+ colResize(e, {pid, idx}) {
281
+ e.preventDefault();
282
+ e.stopPropagation();
283
+ let width;
284
+ let key = `${this.lattice[pid][idx].startRow || 0}:${this.lattice[pid][idx].startCol || idx}`;
285
+ if (!this.$refs[`td_${key}`] || this.lattice[pid][idx].colspan > 1 || this.lattice[pid][idx].rowspan > 1) {
286
+ key = `${pid}:${idx}`;
287
+ }
288
+ const currentResizeElement = this.$refs[`td_${key}`][0];
289
+ const style = this.rule.style[key] || {};
290
+
291
+ const doRowResize = e => {
292
+ if (!this.resize.isResizing) return;
293
+
294
+ const dy = e.clientX - this.resize.startX;
295
+ const newWidth = this.resize.startWidth + dy;
296
+ if (newWidth > 20) {
297
+ currentResizeElement.style.width = `${newWidth}px`;
298
+ width = newWidth;
299
+ }
300
+ };
301
+
302
+ const stopResize = () => {
303
+ if (!this.resize.isResizing) return;
304
+
305
+ this.resize.isResizing = false;
306
+
307
+ style.width = `${width}px`;
308
+
309
+ this.rule.style[key] = style;
310
+
311
+ document.removeEventListener('mousemove', doRowResize);
312
+ document.removeEventListener('mouseup', stopResize);
313
+ };
314
+ this.resize.isResizing = true;
315
+ this.resize.startX = e.clientX;
316
+ this.resize.startWidth = currentResizeElement.offsetWidth;
317
+
318
+ document.addEventListener('mousemove', doRowResize);
319
+ document.addEventListener('mouseup', stopResize);
320
+ },
321
+ mousedown(e, {pid, idx}) {
322
+ if (
323
+ e.button === 0 &&
324
+ !e.target.classList.contains('icon-move') &&
325
+ !e.target.classList.contains('_fd-table-row-handle') &&
326
+ !e.target.classList.contains('_fd-table-col-handle')
327
+ ) {
328
+ e.stopPropagation();
329
+ e.preventDefault();
330
+ if (this.visible) {
331
+ this.visible = false;
332
+ } else {
333
+ this.isSelecting = {pid, idx};
334
+ this.updateSelection({pid, idx});
335
+ }
336
+ }
337
+ },
338
+ mousemove(e, {pid, idx}) {
339
+ if (this.isSelecting) {
340
+ e.stopPropagation();
341
+ if (!this.oldSelection || this.oldSelection.pid !== pid || this.oldSelection.idx !== idx) {
342
+ this.updateSelection({pid, idx});
343
+ this.oldSelection = {pid, idx};
344
+ }
345
+ }
346
+ },
347
+ mouseup() {
348
+ this.isSelecting = null;
349
+ },
350
+ dblclick(e, {pid, idx}) {
351
+ let flag = false;
352
+ this.formCreateInject.children.forEach(child => {
353
+ flag = flag || (child && child.slot === `${pid}:${idx}`);
354
+ });
355
+ if (!flag) {
356
+ const designer = this.designer.setupState;
357
+ designer.dragMenu({
358
+ menu: designer.dragRuleList.text,
359
+ children: this.formCreateInject.children,
360
+ index: this.formCreateInject.children.length,
361
+ slot: `${pid}:${idx}`,
362
+ });
363
+ }
364
+ },
365
+ updateSelection({pid, idx}) {
366
+ const selection = this.selectionRect(this.isSelecting, {pid, idx});
367
+ const {startRow, startCol, endRow, endCol} = this.getSelectionPos({
368
+ startRow: selection[0].pid,
369
+ startCol: selection[0].idx,
370
+ endRow: selection[selection.length - 1].pid,
371
+ endCol: selection[selection.length - 1].idx,
372
+ selection,
373
+ });
374
+ this.selectionPos = {startRow, startCol, endRow, endCol};
375
+ this.selection = this.selectionRect(
376
+ {pid: startRow, idx: startCol},
377
+ {
378
+ pid: endRow,
379
+ idx: endCol,
380
+ },
381
+ true
382
+ );
383
+ },
384
+ getSelectionPos(data) {
385
+ let {startRow, startCol, endRow, endCol} = data;
386
+ const selection =
387
+ data.selection ||
388
+ this.selectionRect(
389
+ {pid: startRow, idx: startCol},
390
+ {
391
+ pid: endRow,
392
+ idx: endCol,
393
+ }
394
+ );
395
+ selection.forEach(item => {
396
+ const cell = this.lattice[item.pid][item.idx];
397
+ if (!cell.show) {
398
+ const startCell = this.lattice[cell.startRow][cell.startCol];
399
+ startRow = Math.min(startRow, cell.startRow);
400
+ startCol = Math.min(startCol, cell.startCol);
401
+ endRow = Math.max(endRow, cell.startRow + startCell.rowspan - 1);
402
+ endCol = Math.max(endCol, cell.startCol + startCell.colspan - 1);
403
+ } else {
404
+ if (cell.rowspan > 1) {
405
+ endRow = Math.max(endRow, item.pid + cell.rowspan - 1);
406
+ }
407
+ if (cell.colspan > 1) {
408
+ endCol = Math.max(endCol, item.idx + cell.colspan - 1);
409
+ }
410
+ }
411
+ });
412
+ if (data.startRow !== startRow || data.endRow !== endRow || data.startCol !== startCol || data.endCol !== endCol) {
413
+ return this.getSelectionPos({startRow, startCol, endRow, endCol});
414
+ }
415
+ return {startRow, startCol, endRow, endCol};
416
+ },
417
+ selectionRect(start, end, flag) {
418
+ const startRow = start.pid;
419
+ const startCol = start.idx;
420
+ const endRow = end.pid;
421
+ const endCol = end.idx;
422
+
423
+ const minRow = Math.min(startRow, endRow);
424
+ const maxRow = Math.max(startRow, endRow);
425
+ const minCol = Math.min(startCol, endCol);
426
+ const maxCol = Math.max(startCol, endCol);
427
+ const selection = [];
428
+
429
+ for (let i = minRow; i <= maxRow; i++) {
430
+ for (let j = minCol; j <= maxCol; j++) {
431
+ selection.push(flag ? `${i}:${j}` : {pid: i, idx: j});
432
+ }
433
+ }
434
+ return selection;
435
+ },
436
+ clearSelection() {
437
+ this.isSelecting = null;
438
+ this.oldSelection = null;
439
+ this.selection = [];
440
+ this.selectionPos = null;
441
+ },
442
+ getUnique(key) {
443
+ if (!this.unique[key]) {
444
+ this.unique[key] = uniqueId();
445
+ }
446
+ return this.unique[key];
447
+ },
448
+ getSlotChildren(slots) {
449
+ const children = [];
450
+ this.formCreateInject.children.forEach(child => {
451
+ if (slots.indexOf(child.slot) > -1) {
452
+ children.push(child);
453
+ }
454
+ });
455
+ return children;
456
+ },
457
+ dragAdd(e, item) {
458
+ const designer = this.designer.setupState;
459
+ const children = this.formCreateInject.children;
460
+ const slot = `${item.pid}:${item.idx}`;
461
+ const rule = e.item._underlying_vm_;
462
+ const flag = designer.addRule && designer.addRule.children === designer.moveRule;
463
+ if (flag) {
464
+ designer.moveRule.splice(designer.moveRule.indexOf(rule), 1);
465
+ }
466
+ let idx = 0;
467
+ const refKey = 'drag' + item.pid + item.idx;
468
+ if (this.$refs[refKey][0].list.length) {
469
+ let beforeRule = this.$refs[refKey][0].list[!e.newIndex ? 0 : e.newIndex - 1];
470
+ idx = children.indexOf(beforeRule) + (e.newIndex ? 1 : 0);
471
+ } else if (children.length) {
472
+ const dragSlotKeys = Object.keys(this.$refs);
473
+ for (let i = dragSlotKeys.indexOf(refKey) - 1; i >= 0; i--) {
474
+ if (!this.$refs[dragSlotKeys[i]] || !this.$refs[dragSlotKeys[i]].length) {
475
+ continue;
476
+ }
477
+ const list = this.$refs[dragSlotKeys[i]][0].list || [];
478
+ if (list.length) {
479
+ idx = children.indexOf(list[list.length - 1]) + 1;
480
+ break;
481
+ }
482
+ }
483
+ }
484
+ e.newIndex = idx;
485
+ if (flag) {
486
+ rule.slot = slot;
487
+ children.splice(e.newIndex, 0, rule);
488
+ designer.added = true;
489
+ designer.handleSortAfter({rule});
490
+ } else {
491
+ designer.dragAdd(children, e, `${item.pid}:${item.idx}`);
492
+ }
493
+ },
494
+ dragEnd(e, item) {
495
+ const designer = this.designer.setupState;
496
+ const children = this.formCreateInject.children;
497
+ const rule = e.item._underlying_vm_;
498
+ const oldIdx = children.indexOf(rule);
499
+ e.newIndex = oldIdx + (e.newIndex - e.oldIndex);
500
+ e.oldIndex = oldIdx;
501
+ designer.dragEnd(this.formCreateInject.children, e, `${item.pid}:${item.idx}`);
502
+ },
503
+ dragStart() {
504
+ this.designer.setupState.dragStart(this.formCreateInject.children);
505
+ },
506
+ dragUnchoose(e) {
507
+ this.designer.setupState.dragUnchoose(this.formCreateInject.children, e);
508
+ },
509
+ initRule() {
510
+ const rule = this.rule;
511
+ if (!rule.style) {
512
+ rule.style = {};
513
+ }
514
+ if (!rule.class) {
515
+ rule.class = {};
516
+ }
517
+ if (!rule.layout) {
518
+ rule.layout = [];
519
+ }
520
+ if (!rule.row) {
521
+ rule.row = 1;
522
+ }
523
+ if (!rule.col) {
524
+ rule.col = 1;
525
+ }
526
+ },
527
+ active(item) {
528
+ const key = `${item.pid}:${item.idx}`;
529
+ this.designer.setupState.customActive({
530
+ name: 'fcTableGrid',
531
+ onPaste: rule => {
532
+ let flag = false;
533
+ this.formCreateInject.children.forEach(child => {
534
+ if (child.slot === key) {
535
+ flag = true;
536
+ child.children.push(rule);
537
+ }
538
+ });
539
+ if (!flag) {
540
+ rule.slot = key;
541
+ this.formCreateInject.children.push(rule);
542
+ }
543
+ },
544
+ style: {
545
+ formData: {
546
+ style: this.rule.style[key] || {},
547
+ class: this.rule.class[key] || '',
548
+ },
549
+ change: (field, value) => {
550
+ if (!value || Object.keys(value).length === 0) {
551
+ delete this.rule[field][key];
552
+ } else {
553
+ this.rule[field][key] = value;
554
+ }
555
+ },
556
+ },
557
+ });
558
+ },
559
+ rmSlot(slot, rmSlot) {
560
+ const slotKey = Object.keys(slot);
561
+ const children = this.formCreateInject.children;
562
+ let del = 0;
563
+ [...children].forEach((child, index) => {
564
+ if (!child.slot) {
565
+ return;
566
+ }
567
+ let idx;
568
+ if (rmSlot.indexOf(child.slot) > -1) {
569
+ children.splice(index - del, 1);
570
+ del++;
571
+ } else if ((idx = slotKey.indexOf(child.slot)) > -1) {
572
+ child.slot = slot[slotKey[idx]];
573
+ }
574
+ });
575
+ rmSlot.forEach(v => {
576
+ delete this.style[v];
577
+ });
578
+ this.loadRule();
579
+ },
580
+ makeMap(layout) {
581
+ let map = [];
582
+ for (let x = layout.top; x < (layout.row || layout.top + 1); x++) {
583
+ for (let y = layout.left; y < (layout.col || layout.left + 1); y++) {
584
+ map.push(`${x}:${y}`);
585
+ }
586
+ }
587
+ return map;
588
+ },
589
+ rmSelectionContent() {
590
+ this.rmSlot({}, this.selection);
591
+ },
592
+ selectionStyle() {
593
+ const oldStyle = {...(this.rule.style[this.selection[0]] || {})};
594
+ const tempStyle = this.selection.reduce((acc, cur) => {
595
+ acc[cur] = {...(this.rule.style[cur] || {})};
596
+ return acc;
597
+ }, {});
598
+ this.designer.setupState.customActive({
599
+ name: 'fcTableGrid',
600
+ style: {
601
+ formData: {
602
+ style: oldStyle,
603
+ class: this.rule.class[this.selection[0]] || '',
604
+ },
605
+ change: (field, value) => {
606
+ this.selection.forEach(key => {
607
+ if (!value || Object.keys(value).length === 0) {
608
+ delete this.rule[field][key];
609
+ } else if (field === 'style') {
610
+ const newStyle = {...tempStyle[key]};
611
+ Object.keys(value).forEach(k => {
612
+ if (value[k] !== oldStyle[k]) {
613
+ newStyle[k] = value[k];
614
+ }
615
+ });
616
+ this.rule[field][key] = newStyle;
617
+ } else {
618
+ this.rule[field][key] = value;
619
+ }
620
+ });
621
+ },
622
+ },
623
+ });
624
+ },
625
+ rmSelectionCol() {
626
+ const len = this.selectionPos.endCol - this.selectionPos.startCol + 1;
627
+ const slot = {};
628
+ for (let index = 0; index < this.rule.row; index++) {
629
+ for (let idx = this.selectionPos.endCol + 1; idx < this.rule.col; idx++) {
630
+ slot[`${index}:${idx}`] = `${index}:${idx - len}`;
631
+ }
632
+ }
633
+ const layout = this.filterSelectionLayout();
634
+ layout.forEach(v => {
635
+ if (v.left > this.selectionPos.startCol) {
636
+ v.left -= len;
637
+ }
638
+ });
639
+ this.rule.layout = layout;
640
+ if (this.rule.col - len <= 0) {
641
+ this.formCreateInject.children.splice(0, this.formCreateInject.children.length);
642
+ } else {
643
+ this.rmSlot(
644
+ slot,
645
+ this.selectionRect(
646
+ {pid: 0, idx: this.selectionPos.startCol},
647
+ {
648
+ pid: this.rule.row,
649
+ idx: this.selectionPos.endCol,
650
+ },
651
+ true
652
+ )
653
+ );
654
+ }
655
+ this.rule.col = Math.max(1, this.rule.col - len);
656
+ this.clearSelection();
657
+ },
658
+ rmSelectionRow() {
659
+ const len = this.selectionPos.endRow - this.selectionPos.startRow + 1;
660
+ const slot = {};
661
+ for (let index = this.selectionPos.endRow + 1; index < this.rule.row; index++) {
662
+ for (let idx = 0; idx < this.rule.col; idx++) {
663
+ slot[`${index}:${idx}`] = `${index - len}:${idx}`;
664
+ }
665
+ }
666
+ const layout = this.filterSelectionLayout();
667
+ layout.forEach(v => {
668
+ if (v.top > this.selectionPos.startRow) {
669
+ v.top -= len;
670
+ }
671
+ });
672
+ this.rule.layout = layout;
673
+ if (this.rule.row - len <= 0) {
674
+ this.formCreateInject.children.splice(0, this.formCreateInject.children.length);
675
+ } else {
676
+ this.rmSlot(
677
+ slot,
678
+ this.selectionRect(
679
+ {
680
+ pid: this.selectionPos.startRow,
681
+ idx: 0,
682
+ },
683
+ {pid: this.selectionPos.endRow, idx: this.rule.col},
684
+ true
685
+ )
686
+ );
687
+ }
688
+ this.rule.row = Math.max(1, this.rule.row - len);
689
+ this.clearSelection();
690
+ },
691
+ filterSelectionLayout() {
692
+ return (this.rule.layout || []).filter(item => {
693
+ return (
694
+ item.top < this.selectionPos.startRow ||
695
+ item.top > this.selectionPos.endRow ||
696
+ item.left < this.selectionPos.startCol ||
697
+ item.left > this.selectionPos.endCol
698
+ );
699
+ });
700
+ },
701
+ mergeSelection(split) {
702
+ const layout = this.filterSelectionLayout();
703
+ if (!split) {
704
+ layout.push({
705
+ top: this.selectionPos.startRow,
706
+ left: this.selectionPos.startCol,
707
+ row: this.selectionPos.endRow - this.selectionPos.startRow + 1,
708
+ col: this.selectionPos.endCol - this.selectionPos.startCol + 1,
709
+ });
710
+ const slot = {};
711
+ for (let index = this.selectionPos.startRow; index <= this.selectionPos.endRow; index++) {
712
+ for (let idx = this.selectionPos.startCol; idx <= this.selectionPos.endCol; idx++) {
713
+ slot[`${index}:${idx}`] = `${this.selectionPos.startRow}:${this.selectionPos.startCol}`;
714
+ }
715
+ }
716
+ this.rmSlot(slot, []);
717
+ }
718
+ this.rule.layout = layout;
719
+ this.loadRule();
720
+ },
721
+ addCol(row, type) {
722
+ this.clearSelection();
723
+ this.rule.col++;
724
+ this.rule.layout.forEach(v => {
725
+ if (v.left > (type ? row.idx - 1 : row.idx)) {
726
+ v.left++;
727
+ }
728
+ });
729
+ if (type || row.idx < this.rule.col - 2) {
730
+ const slot = {};
731
+ for (let index = 0; index < this.rule.row; index++) {
732
+ for (let idx = type ? row.idx - 1 : row.idx + 1; idx < this.rule.col - 1; idx++) {
733
+ slot[`${index}:${idx}`] = `${index}:${idx + 1}`;
734
+ }
735
+ }
736
+ const slotKey = Object.keys(slot);
737
+ this.formCreateInject.children.forEach(child => {
738
+ let idx;
739
+ if (child.slot && (idx = slotKey.indexOf(child.slot)) > -1) {
740
+ child.slot = slot[slotKey[idx]];
741
+ }
742
+ });
743
+ slotKey.forEach(v => {
744
+ if (this.style[v]) {
745
+ this.style[slot[v]] = this.style[v];
746
+ delete this.style[v];
747
+ }
748
+ });
749
+ }
750
+ this.loadRule();
751
+ },
752
+ addRow(row, type) {
753
+ this.clearSelection();
754
+ this.rule.row++;
755
+ this.rule.layout.forEach(v => {
756
+ if (v.top > (type ? row.pid - 1 : row.pid)) {
757
+ v.top++;
758
+ }
759
+ });
760
+ if (type || row.pid < this.rule.row - 2) {
761
+ const slot = {};
762
+ for (let index = type ? row.pid - 1 : row.pid + 1; index < this.rule.row; index++) {
763
+ for (let idx = 0; idx < this.rule.col; idx++) {
764
+ slot[`${index}:${idx}`] = `${index + 1}:${idx}`;
765
+ }
766
+ }
767
+ const slotKey = Object.keys(slot);
768
+ this.formCreateInject.children.forEach(child => {
769
+ let idx;
770
+ if (child.slot && (idx = slotKey.indexOf(child.slot)) > -1) {
771
+ child.slot = slot[slotKey[idx]];
772
+ }
773
+ });
774
+ slotKey.reverse().forEach(v => {
775
+ if (this.style[v]) {
776
+ this.style[slot[v]] = this.style[v];
777
+ delete this.style[v];
778
+ }
779
+ });
780
+ }
781
+ this.loadRule();
782
+ },
783
+ loadRule() {
784
+ const lattice = [];
785
+ const rule = this.rule || {row: 1, col: 1};
786
+ for (let index = 0; index < rule.row; index++) {
787
+ const sub = [];
788
+ lattice.push(sub);
789
+ for (let idx = 0; idx < rule.col; idx++) {
790
+ sub.push({rowspan: 1, colspan: 1, slot: [], show: true, id: this.getUnique(`${index}${idx}`)});
791
+ }
792
+ }
793
+ [...(rule.layout || [])].forEach((v, i) => {
794
+ if (
795
+ ((!v.row || v.row <= 0) && (!v.col || v.col <= 0)) ||
796
+ !lattice[v.top] ||
797
+ !lattice[v.top][v.left] ||
798
+ !lattice[v.top][v.left].show
799
+ ) {
800
+ rule.layout.splice(i, 1);
801
+ return;
802
+ }
803
+ const data = lattice[v.top][v.left];
804
+ data.layout = v;
805
+ let col = 1;
806
+ let row = 1;
807
+ if (v.col) {
808
+ col = v.col + v.left > rule.col ? rule.col - v.left : v.col;
809
+ data.colspan = col;
810
+ }
811
+ if (v.row) {
812
+ row = v.row + v.top > rule.row ? rule.row - v.top : v.row;
813
+ data.rowspan = row;
814
+ }
815
+ if (row && col) {
816
+ for (let index = 0; index < row; index++) {
817
+ const row = lattice[v.top + index];
818
+ if (row) {
819
+ for (let idx = 0; idx < col; idx++) {
820
+ if (!idx && !index) continue;
821
+
822
+ if (row[v.left + idx]) {
823
+ row[v.left + idx].show = false;
824
+ row[v.left + idx].startRow = v.top;
825
+ row[v.left + idx].startCol = v.left;
826
+ }
827
+ data.slot.push(`${v.top + index}:${v.left + idx}`);
828
+ }
829
+ }
830
+ }
831
+ }
832
+ });
833
+
834
+ const checkCol = col => {
835
+ return !!(!col || col.layout || !col.show);
836
+ };
837
+
838
+ lattice.forEach((v, index) => {
839
+ v.forEach((item, idx) => {
840
+ let right = false;
841
+ let bottom = false;
842
+ if (item.layout) {
843
+ const col = item.layout.col || 1;
844
+ const row = item.layout.row || 1;
845
+ for (let i = 0; i < col; i++) {
846
+ if (!lattice[index + row] || checkCol(lattice[index + row][idx + i])) {
847
+ bottom = true;
848
+ continue;
849
+ }
850
+ }
851
+ for (let i = 0; i < row; i++) {
852
+ if (!lattice[index + i] || checkCol(lattice[index + i][idx + col])) {
853
+ right = true;
854
+ continue;
855
+ }
856
+ }
857
+ } else {
858
+ right = checkCol(v[idx + 1]);
859
+ bottom = lattice[index + 1] ? checkCol(lattice[index + 1][idx]) : true;
860
+ }
861
+ item.right = right;
862
+ item.bottom = bottom;
863
+ });
864
+ });
865
+ this.lattice = lattice;
866
+ this.formCreateInject.rule.props.rule = rule;
867
+ },
868
+ hideMenu() {
869
+ this.visible = false;
870
+ },
871
+ },
872
+ beforeMount() {
873
+ this.loadRule();
874
+ },
875
+ mounted() {
876
+ document.addEventListener('click', this.hideMenu, true);
877
+ },
878
+ beforeUnmount() {
879
+ document.removeEventListener('click', this.hideMenu, true);
880
+ },
881
+ });
882
+ </script>
883
+
884
+ <style>
885
+ ._fd-table-view {
886
+ overflow: auto;
887
+ }
888
+
889
+ ._fd-table-view-cell {
890
+ min-height: 50px;
891
+ height: 100%;
892
+ position: relative;
893
+ }
894
+
895
+ ._fd-table-row-handle {
896
+ position: absolute;
897
+ left: 0;
898
+ bottom: -4px;
899
+ width: 100%;
900
+ height: 8px;
901
+ cursor: row-resize;
902
+ z-index: 1;
903
+ background-color: transparent;
904
+ }
905
+
906
+ ._fd-table-col-handle {
907
+ position: absolute;
908
+ top: 0;
909
+ right: -4px;
910
+ width: 8px;
911
+ height: 100%;
912
+ cursor: col-resize;
913
+ z-index: 1;
914
+ background-color: transparent;
915
+ }
916
+
917
+ ._fd-table-view-cell.selected > ._fd-drag-tool {
918
+ background-color: rgba(46, 115, 255, 0.05);
919
+ outline: 1px solid #2E73FF;
920
+ }
921
+
922
+ ._fd-table-view-cell > ._fd-drag-tool {
923
+ height: 100%;
924
+ width: 100%;
925
+ min-width: unset;
926
+ border: 0;
927
+ outline: 0;
928
+ margin: 0;
929
+ max-width: 100%;
930
+ max-height: 100%;
931
+ }
932
+
933
+ ._fd-table-view ._fd-table-view-cell > ._fd-drag-tool > ._fd-tableCell-drag {
934
+ min-height: 80px;
935
+ display: flex;
936
+ flex-direction: row;
937
+ flex-wrap: wrap;
938
+ align-content: center;
939
+ align-items: center;
940
+ justify-content: center;
941
+ text-align: center;
942
+ }
943
+
944
+ ._fd-table-view ._fd-table-view-cell [class*='_fd-fcTable-slot'] {
945
+ align-content: center;
946
+ align-items: center;
947
+ justify-content: center;
948
+ text-align: center;
949
+ }
950
+
951
+ ._fd-table-view-btn {
952
+ flex-direction: column;
953
+ padding: 0;
954
+ }
955
+
956
+ ._fd-table-view-btn .fc-icon {
957
+ width: 18px;
958
+ color: #fff;
959
+ font-size: 16px;
960
+ }
961
+
962
+ ._fd-table-view > table {
963
+ width: 100%;
964
+ height: 100%;
965
+ overflow: hidden;
966
+ table-layout: fixed;
967
+ border: 1px solid #EBEEF5;
968
+ border-bottom: 0 none;
969
+ border-right: 0 none;
970
+ border-collapse: collapse;
971
+ }
972
+
973
+ ._fd-table-view tr {
974
+ min-height: 50px;
975
+ }
976
+
977
+ ._fd-table-view td {
978
+ padding: 0;
979
+ min-height: 50px;
980
+ min-width: 80px;
981
+ position: relative;
982
+ box-sizing: border-box;
983
+ overflow-wrap: break-word;
984
+ white-space: nowrap;
985
+ border: 1px solid #EBEEF5;
986
+ }
987
+
988
+ ._fd-tableCell-drag {
989
+ height: 100%;
990
+ }
991
+
992
+ ._fd-table-view.is-mini td {
993
+ padding: 0;
994
+ min-height: 12px;
995
+ }
996
+
997
+ ._fd-table-view.is-mini .el-form-item {
998
+ padding: 0;
999
+ margin: 0;
1000
+ }
1001
+
1002
+ ._fd-table-view.is-table-form .el-form-item {
1003
+ margin-bottom: 1px;
1004
+ }
1005
+
1006
+ ._fd-table-view.is-table-form .el-form-item.is-error {
1007
+ margin-bottom: 22px;
1008
+ }
1009
+
1010
+ ._fd-table-view.is-table-form .el-form-item__label,
1011
+ ._fd-table-view.is-table-form .van-field__label {
1012
+ display: none !important;
1013
+ }
1014
+
1015
+ ._fd-table-view.is-table-form .el-form-item__content {
1016
+ display: flex;
1017
+ margin-left: 0 !important;
1018
+ width: 100% !important;
1019
+ }
1020
+
1021
+ ._fd-table-view.is-table-form .el-input-number,
1022
+ ._fd-table-view.is-table-form .el-select,
1023
+ ._fd-table-view.is-table-form .el-slider,
1024
+ ._fd-table-view.is-table-form .el-cascader,
1025
+ ._fd-table-view.is-table-form .el-date-editor {
1026
+ width: 100%;
1027
+ }
1028
+
1029
+ ._fd-table-context-menu {
1030
+ position: fixed;
1031
+ display: block;
1032
+ background-color: white;
1033
+ border: 1px solid #ddd;
1034
+ z-index: 1905;
1035
+ min-width: 120px;
1036
+ font-size: 14px;
1037
+ box-shadow: 0px 1px 10px 0px rgba(0, 0, 0, 0.1);
1038
+ border-radius: 6px;
1039
+ padding: 6px 0;
1040
+ color: #666666;
1041
+ }
1042
+
1043
+ ._fd-table-context-menuitem {
1044
+ line-height: 22px;
1045
+ padding: 5px 16px;
1046
+ cursor: pointer;
1047
+ }
1048
+
1049
+ ._fd-table-context-menuitem:hover {
1050
+ background-color: #f0f0f0;
1051
+ }
1052
+
1053
+ ._fd-table-context-menu-separator {
1054
+ height: 1px;
1055
+ background-color: #eee;
1056
+ margin: 6px 0;
1057
+ }
1058
+ </style>