@tmagic/form 1.2.0-beta.2 → 1.2.0-beta.4

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 (66) hide show
  1. package/dist/tmagic-form.mjs +2081 -2500
  2. package/dist/tmagic-form.mjs.map +1 -1
  3. package/dist/tmagic-form.umd.js +2104 -2524
  4. package/dist/tmagic-form.umd.js.map +1 -1
  5. package/package.json +3 -4
  6. package/src/Form.vue +116 -159
  7. package/src/FormDialog.vue +104 -126
  8. package/src/containers/Col.vue +22 -38
  9. package/src/containers/Container.vue +135 -171
  10. package/src/containers/Fieldset.vue +11 -7
  11. package/src/containers/GroupList.vue +80 -112
  12. package/src/containers/GroupListItem.vue +87 -124
  13. package/src/containers/Panel.vue +26 -49
  14. package/src/containers/Row.vue +18 -40
  15. package/src/containers/Step.vue +36 -48
  16. package/src/containers/Table.vue +437 -478
  17. package/src/containers/Tabs.vue +89 -118
  18. package/src/fields/Cascader.vue +88 -136
  19. package/src/fields/Checkbox.vue +46 -50
  20. package/src/fields/CheckboxGroup.vue +39 -35
  21. package/src/fields/ColorPicker.vue +4 -2
  22. package/src/fields/Date.vue +20 -26
  23. package/src/fields/DateTime.vue +31 -39
  24. package/src/fields/Daterange.vue +3 -2
  25. package/src/fields/DynamicField.vue +63 -77
  26. package/src/fields/Link.vue +65 -86
  27. package/src/fields/Number.vue +32 -34
  28. package/src/fields/RadioGroup.vue +23 -23
  29. package/src/fields/Select.vue +294 -310
  30. package/src/fields/SelectOptionGroups.vue +10 -5
  31. package/src/fields/SelectOptions.vue +4 -2
  32. package/src/fields/Switch.vue +46 -49
  33. package/src/fields/Text.vue +99 -107
  34. package/src/fields/Textarea.vue +32 -44
  35. package/src/fields/Time.vue +19 -30
  36. package/src/index.ts +22 -23
  37. package/src/schema.ts +45 -12
  38. package/types/Form.vue.d.ts +213 -111
  39. package/types/FormDialog.vue.d.ts +812 -155
  40. package/types/containers/Col.vue.d.ts +94 -40
  41. package/types/containers/Container.vue.d.ts +124 -65
  42. package/types/containers/GroupList.vue.d.ts +88 -53
  43. package/types/containers/GroupListItem.vue.d.ts +99 -67
  44. package/types/containers/Panel.vue.d.ts +92 -39
  45. package/types/containers/Row.vue.d.ts +94 -39
  46. package/types/containers/Step.vue.d.ts +104 -42
  47. package/types/containers/Table.vue.d.ts +157 -130
  48. package/types/containers/Tabs.vue.d.ts +95 -50
  49. package/types/fields/Cascader.vue.d.ts +97 -71
  50. package/types/fields/Checkbox.vue.d.ts +97 -56
  51. package/types/fields/CheckboxGroup.vue.d.ts +97 -53
  52. package/types/fields/Date.vue.d.ts +97 -54
  53. package/types/fields/DateTime.vue.d.ts +97 -54
  54. package/types/fields/DynamicField.vue.d.ts +97 -64
  55. package/types/fields/Link.vue.d.ts +62 -657
  56. package/types/fields/Number.vue.d.ts +101 -56
  57. package/types/fields/RadioGroup.vue.d.ts +98 -52
  58. package/types/fields/Select.vue.d.ts +99 -65
  59. package/types/fields/Switch.vue.d.ts +97 -56
  60. package/types/fields/Text.vue.d.ts +100 -57
  61. package/types/fields/Textarea.vue.d.ts +102 -60
  62. package/types/fields/Time.vue.d.ts +97 -55
  63. package/types/index.d.ts +0 -1
  64. package/types/schema.d.ts +37 -9
  65. package/src/utils/fieldProps.ts +0 -39
  66. package/types/utils/fieldProps.d.ts +0 -21
@@ -2,10 +2,10 @@
2
2
  <div ref="mTable" class="m-fields-table" :class="{ 'm-fields-table-item-extra': config.itemExtra }">
3
3
  <span v-if="config.extra" style="color: rgba(0, 0, 0, 0.45)" v-html="config.extra"></span>
4
4
  <div class="el-form-item__content">
5
- <el-tooltip content="拖拽可排序" placement="left-start" :disabled="config.dropSort !== true">
6
- <el-table
5
+ <TMagicTooltip content="拖拽可排序" placement="left-start" :disabled="config.dropSort !== true">
6
+ <TMagicTable
7
7
  v-if="model[modelName]"
8
- ref="elTable"
8
+ ref="tMagicTable"
9
9
  style="width: 100%"
10
10
  :data="model[modelName]"
11
11
  :border="config.border"
@@ -15,31 +15,36 @@
15
15
  @select="selectHandle"
16
16
  @sort-change="sortChange"
17
17
  >
18
- <el-table-column v-if="config.itemExtra" :fixed="'left'" width="30" type="expand">
18
+ <TMagicTableColumn v-if="config.itemExtra" :fixed="'left'" width="30" type="expand">
19
19
  <template v-slot="scope">
20
20
  <span v-html="itemExtra(config.itemExtra, scope.$index)" class="m-form-tip"></span>
21
21
  </template>
22
- </el-table-column>
22
+ </TMagicTableColumn>
23
23
 
24
- <el-table-column label="操作" width="55" align="center" :fixed="config.fixed === false ? undefined : 'left'">
24
+ <TMagicTableColumn
25
+ label="操作"
26
+ width="55"
27
+ align="center"
28
+ :fixed="config.fixed === false ? undefined : 'left'"
29
+ >
25
30
  <template v-slot="scope">
26
- <el-icon
31
+ <TMagicIcon
27
32
  v-show="showDelete(scope.$index + 1 + pagecontext * pagesize - 1)"
28
33
  class="m-table-delete-icon"
29
34
  @click="removeHandler(scope.$index + 1 + pagecontext * pagesize - 1)"
30
35
  ><Delete
31
- /></el-icon>
36
+ /></TMagicIcon>
32
37
  </template>
33
- </el-table-column>
38
+ </TMagicTableColumn>
34
39
 
35
- <el-table-column v-if="sort && model[modelName] && model[modelName].length > 1" label="排序" width="60">
40
+ <TMagicTableColumn v-if="sort && model[modelName] && model[modelName].length > 1" label="排序" width="60">
36
41
  <template v-slot="scope">
37
- <el-tooltip
42
+ <TMagicTooltip
43
+ v-if="scope.$index + 1 + pagecontext * pagesize - 1 !== 0"
38
44
  content="点击上移,双击置顶"
39
45
  placement="top"
40
- v-if="scope.$index + 1 + pagecontext * pagesize - 1 !== 0"
41
46
  >
42
- <el-button
47
+ <TMagicButton
43
48
  plain
44
49
  size="small"
45
50
  type="primary"
@@ -47,14 +52,14 @@
47
52
  text
48
53
  @click="upHandler(scope.$index + 1 + pagecontext * pagesize - 1)"
49
54
  @dblclick="topHandler(scope.$index + 1 + pagecontext * pagesize - 1)"
50
- ></el-button>
51
- </el-tooltip>
52
- <el-tooltip
55
+ ></TMagicButton>
56
+ </TMagicTooltip>
57
+ <TMagicTooltip
58
+ v-if="scope.$index + 1 + pagecontext * pagesize - 1 !== model[modelName].length - 1"
53
59
  content="点击下移,双击置底"
54
60
  placement="top"
55
- v-if="scope.$index + 1 + pagecontext * pagesize - 1 !== model[modelName].length - 1"
56
61
  >
57
- <el-button
62
+ <TMagicButton
58
63
  plain
59
64
  size="small"
60
65
  type="primary"
@@ -62,25 +67,25 @@
62
67
  text
63
68
  @click="downHandler(scope.$index + 1 + pagecontext * pagesize - 1)"
64
69
  @dblclick="bottomHandler(scope.$index + 1 + pagecontext * pagesize - 1)"
65
- ></el-button>
66
- </el-tooltip>
70
+ ></TMagicButton>
71
+ </TMagicTooltip>
67
72
  </template>
68
- </el-table-column>
73
+ </TMagicTableColumn>
69
74
 
70
- <el-table-column
75
+ <TMagicTableColumn
71
76
  v-if="selection"
72
77
  align="center"
73
78
  header-align="center"
74
79
  type="selection"
75
80
  width="45"
76
- ></el-table-column>
81
+ ></TMagicTableColumn>
77
82
 
78
- <el-table-column width="60" label="序号" v-if="showIndex && config.showIndex">
83
+ <TMagicTableColumn width="60" label="序号" v-if="showIndex && config.showIndex">
79
84
  <template v-slot="scope">{{ scope.$index + 1 + pagecontext * pagesize }}</template>
80
- </el-table-column>
85
+ </TMagicTableColumn>
81
86
 
82
87
  <template v-for="(column, index) in config.items">
83
- <el-table-column
88
+ <TMagicTableColumn
84
89
  v-if="column.type !== 'hidden' && display(column.display)"
85
90
  :prop="column.name"
86
91
  :width="column.width"
@@ -91,7 +96,7 @@
91
96
  :class-name="config.dropSort === true ? 'el-table__column--dropable' : ''"
92
97
  >
93
98
  <template #default="scope">
94
- <m-form-container
99
+ <Container
95
100
  v-if="scope.$index > -1"
96
101
  labelWidth="0"
97
102
  :prop="getProp(scope.$index)"
@@ -100,18 +105,23 @@
100
105
  :model="scope.row"
101
106
  :size="size"
102
107
  @change="$emit('change', model[modelName])"
103
- ></m-form-container>
108
+ ></Container>
104
109
  </template>
105
- </el-table-column>
110
+ </TMagicTableColumn>
106
111
  </template>
107
- </el-table>
108
- </el-tooltip>
112
+ </TMagicTable>
113
+ </TMagicTooltip>
109
114
  <slot></slot>
110
- <el-button v-if="addable" size="small" type="primary" plain @click="newHandler()">添加</el-button> &nbsp;
111
- <el-button :icon="Grid" size="small" type="primary" @click="toggleMode" v-if="enableToggleMode && !isFullscreen"
112
- >展开配置</el-button
115
+ <TMagicButton v-if="addable" size="small" type="primary" plain @click="newHandler()">添加</TMagicButton> &nbsp;
116
+ <TMagicButton
117
+ :icon="Grid"
118
+ size="small"
119
+ type="primary"
120
+ @click="toggleMode"
121
+ v-if="enableToggleMode && !isFullscreen"
122
+ >展开配置</TMagicButton
113
123
  >
114
- <el-button
124
+ <TMagicButton
115
125
  :icon="FullScreen"
116
126
  size="small"
117
127
  type="primary"
@@ -119,8 +129,8 @@
119
129
  v-if="config.enableFullscreen !== false"
120
130
  >
121
131
  {{ isFullscreen ? '退出全屏' : '全屏编辑' }}
122
- </el-button>
123
- <el-upload
132
+ </TMagicButton>
133
+ <TMagicUpload
124
134
  v-if="importable"
125
135
  ref="excelBtn"
126
136
  action="/noop"
@@ -128,13 +138,13 @@
128
138
  :auto-upload="false"
129
139
  style="display: inline-block"
130
140
  >
131
- <el-button size="small" type="success" plain>导入EXCEL</el-button> </el-upload
141
+ <TMagicButton size="small" type="success" plain>导入EXCEL</TMagicButton> </TMagicUpload
132
142
  >&nbsp;
133
- <el-button v-if="importable" size="small" type="warning" plain @click="clearHandler()">清空</el-button>
143
+ <TMagicButton v-if="importable" size="small" type="warning" plain @click="clearHandler()">清空</TMagicButton>
134
144
  </div>
135
145
 
136
146
  <div class="bottom" style="text-align: right">
137
- <el-pagination
147
+ <TMagicPagination
138
148
  layout="total, sizes, prev, pager, next, jumper"
139
149
  :hide-on-single-page="model[modelName].length < pagesize"
140
150
  :current-page="pagecontext + 1"
@@ -144,470 +154,419 @@
144
154
  @size-change="handleSizeChange"
145
155
  @current-change="handleCurrentChange"
146
156
  >
147
- </el-pagination>
157
+ </TMagicPagination>
148
158
  </div>
149
159
  </div>
150
160
  </template>
151
161
 
152
- <script lang="ts">
153
- /* eslint-disable no-param-reassign */
154
- import { computed, defineComponent, inject, onMounted, PropType, ref, toRefs } from 'vue';
162
+ <script setup lang="ts">
163
+ import { computed, inject, onMounted, ref, toRefs } from 'vue';
155
164
  import { ArrowDown, ArrowUp, Delete, FullScreen, Grid } from '@element-plus/icons-vue';
156
- import { ElMessage, UploadFile } from 'element-plus';
157
165
  import { cloneDeep } from 'lodash-es';
158
166
  import Sortable, { SortableEvent } from 'sortablejs';
159
167
 
168
+ import {
169
+ TMagicButton,
170
+ TMagicIcon,
171
+ tMagicMessage,
172
+ TMagicPagination,
173
+ TMagicTable,
174
+ TMagicTableColumn,
175
+ TMagicTooltip,
176
+ TMagicUpload,
177
+ } from '@tmagic/design';
160
178
  import { asyncLoadJs, sleep } from '@tmagic/utils';
161
179
 
162
180
  import { ColumnConfig, FormState, SortProp, TableConfig } from '../schema';
163
- import { display, initValue } from '../utils/form';
164
-
165
- export default defineComponent({
166
- props: {
167
- name: {
168
- type: String,
169
- required: true,
170
- },
171
-
172
- model: {
173
- type: Object,
174
- required: true,
175
- default: () => ({}),
176
- },
177
-
178
- config: {
179
- type: Object as PropType<TableConfig>,
180
- required: true,
181
- default: () => ({}),
182
- },
183
-
184
- prop: {
185
- type: String,
186
- },
187
-
188
- labelWidth: {
189
- type: String,
190
- },
191
-
192
- sort: {
193
- type: Boolean,
194
- default: false,
195
- },
196
-
197
- sortKey: {
198
- type: String,
199
- default: '',
200
- },
201
-
202
- text: {
203
- type: String,
204
- },
205
-
206
- size: String,
207
-
208
- enableToggleMode: {
209
- type: Boolean,
210
- default: true,
211
- },
212
-
213
- showIndex: {
214
- type: Boolean,
215
- default: true,
216
- },
181
+ import { display as displayFunc, initValue } from '../utils/form';
182
+
183
+ import Container from './Container.vue';
184
+
185
+ const props = withDefaults(
186
+ defineProps<{
187
+ model: any;
188
+ config: TableConfig;
189
+ name: string;
190
+ prop?: string;
191
+ labelWidth?: string;
192
+ sort?: boolean;
193
+ sortKey?: string;
194
+ text?: string;
195
+ size?: string;
196
+ enableToggleMode?: boolean;
197
+ showIndex?: boolean;
198
+ }>(),
199
+ {
200
+ prop: '',
201
+ sortKey: '',
202
+ enableToggleMode: true,
203
+ showIndex: true,
217
204
  },
218
-
219
- emits: ['change', 'select'],
220
-
221
- components: { Delete },
222
-
223
- setup(props, { emit }) {
224
- let timer: any | null = null;
225
- const mForm = inject<FormState | undefined>('mForm');
226
-
227
- const elTable = ref<any>();
228
- const excelBtn = ref<any>();
229
- const mTable = ref<HTMLDivElement>();
230
-
231
- const pagesize = ref(10);
232
- const pagecontext = ref(0);
233
- const updateKey = ref(1);
234
- const isFullscreen = ref(false);
235
-
236
- const modelName = computed(() => props.name || props.config.name || '');
237
-
238
- const sortChange = ({ prop, order }: SortProp) => {
239
- if (order === 'ascending') {
240
- props.model[modelName.value] = props.model[modelName.value].sort((a: any, b: any) => a[prop] - b[prop]);
241
- } else if (order === 'descending') {
242
- props.model[modelName.value] = props.model[modelName.value].sort((a: any, b: any) => b[prop] - a[prop]);
243
- }
244
- };
245
-
246
- const foreUpdate = () => {
247
- updateKey.value += 1;
248
- setTimeout(() => rowDrop());
249
- };
250
-
251
- const swapArray = (index1: number, index2: number) => {
252
- [props.model[modelName.value][index1]] = props.model[modelName.value].splice(
253
- index2,
254
- 1,
255
- props.model[modelName.value][index1],
256
- );
257
- if (props.sortKey) {
258
- for (let i = props.model[modelName.value].length - 1, v = 0; i >= 0; i--, v++) {
259
- props.model[modelName.value][v][props.sortKey] = i;
260
- }
261
- }
262
- mForm?.$emit('field-change', props.prop, props.model[modelName.value]);
263
- };
264
-
265
- const rowDrop = () => {
266
- const tableEl = elTable.value?.$el;
267
- if (tableEl?.querySelectorAll('.el-table__body > tbody')) {
268
- // eslint-disable-next-line prefer-destructuring
269
- const el = tableEl.querySelectorAll('.el-table__body > tbody')[0];
270
- const sortable = Sortable.create(el, {
271
- onEnd: ({ newIndex, oldIndex }: SortableEvent) => {
272
- if (typeof newIndex === 'undefined') return;
273
- if (typeof oldIndex === 'undefined') return;
274
- swapArray(newIndex, oldIndex);
275
- emit('change', props.model[modelName.value]);
276
- foreUpdate();
277
- sortable.destroy();
278
- mForm?.$emit('field-change', props.prop, props.model[modelName.value]);
205
+ );
206
+
207
+ const emit = defineEmits(['change', 'select']);
208
+
209
+ let timer: any | null = null;
210
+ const mForm = inject<FormState | undefined>('mForm');
211
+
212
+ const tMagicTable = ref<InstanceType<typeof TMagicTable>>();
213
+ const excelBtn = ref<InstanceType<typeof TMagicUpload>>();
214
+ const mTable = ref<HTMLDivElement>();
215
+
216
+ const pagesize = ref(10);
217
+ const pagecontext = ref(0);
218
+ const updateKey = ref(1);
219
+ const isFullscreen = ref(false);
220
+
221
+ const modelName = computed(() => props.name || props.config.name || '');
222
+
223
+ const sortChange = ({ prop, order }: SortProp) => {
224
+ if (order === 'ascending') {
225
+ props.model[modelName.value] = props.model[modelName.value].sort((a: any, b: any) => a[prop] - b[prop]);
226
+ } else if (order === 'descending') {
227
+ props.model[modelName.value] = props.model[modelName.value].sort((a: any, b: any) => b[prop] - a[prop]);
228
+ }
229
+ };
230
+
231
+ const foreUpdate = () => {
232
+ updateKey.value += 1;
233
+ setTimeout(() => rowDrop());
234
+ };
235
+
236
+ const swapArray = (index1: number, index2: number) => {
237
+ [props.model[modelName.value][index1]] = props.model[modelName.value].splice(
238
+ index2,
239
+ 1,
240
+ props.model[modelName.value][index1],
241
+ );
242
+ if (props.sortKey) {
243
+ for (let i = props.model[modelName.value].length - 1, v = 0; i >= 0; i--, v++) {
244
+ props.model[modelName.value][v][props.sortKey] = i;
245
+ }
246
+ }
247
+ mForm?.$emit('field-change', props.prop, props.model[modelName.value]);
248
+ };
249
+
250
+ const rowDrop = () => {
251
+ const tableEl = tMagicTable.value?.$el;
252
+ if (tableEl?.querySelectorAll('.el-table__body > tbody')) {
253
+ // eslint-disable-next-line prefer-destructuring
254
+ const el = tableEl.querySelectorAll('.el-table__body > tbody')[0];
255
+ const sortable = Sortable.create(el, {
256
+ onEnd: ({ newIndex, oldIndex }: SortableEvent) => {
257
+ if (typeof newIndex === 'undefined') return;
258
+ if (typeof oldIndex === 'undefined') return;
259
+ swapArray(newIndex, oldIndex);
260
+ emit('change', props.model[modelName.value]);
261
+ foreUpdate();
262
+ sortable.destroy();
263
+ mForm?.$emit('field-change', props.prop, props.model[modelName.value]);
264
+ sleep(1000).then(() => {
265
+ const eltrs = tableEl.querySelectorAll('.el-table__body > tbody > tr');
266
+ if (eltrs?.[newIndex]) {
267
+ eltrs[newIndex].style.backgroundColor = 'rgba(243, 89, 59, 0.2)';
279
268
  sleep(1000).then(() => {
280
- const eltrs = tableEl.querySelectorAll('.el-table__body > tbody > tr');
281
- if (eltrs?.[newIndex]) {
282
- eltrs[newIndex].style.backgroundColor = 'rgba(243, 89, 59, 0.2)';
283
- sleep(1000).then(() => {
284
- eltrs[newIndex].style.backgroundColor = '';
285
- });
286
- }
269
+ eltrs[newIndex].style.backgroundColor = '';
287
270
  });
288
- },
289
- });
290
- }
291
- };
292
-
293
- const newHandler = async (row?: any) => {
294
- if (props.config.max && props.model[modelName.value].length >= props.config.max) {
295
- ElMessage.error(`最多新增配置不能超过${props.config.max}条`);
296
- return;
297
- }
298
-
299
- const columns = props.config.items;
300
- const enumValues = props.config.enum || [];
301
- let enumV = [];
302
- const { length } = props.model[modelName.value];
303
- const key = props.config.key || 'id';
304
- let inputs: any = {};
305
-
306
- if (enumValues.length) {
307
- if (length >= enumValues.length) {
308
- return;
309
- }
310
- enumV = enumValues.filter((item) => {
311
- let i = 0;
312
- for (; i < length; i++) {
313
- if (item[key] === props.model[modelName.value][i][key]) {
314
- break;
315
- }
316
271
  }
317
- return i === length;
318
- });
319
-
320
- if (enumV.length > 0) {
321
- // eslint-disable-next-line prefer-destructuring
322
- inputs = enumV[0];
323
- }
324
- } else if (Array.isArray(row)) {
325
- columns.forEach((column, index) => {
326
- column.name && (inputs[column.name] = row[index]);
327
272
  });
328
- } else {
329
- if (typeof props.config.defaultAdd === 'function') {
330
- inputs = await props.config.defaultAdd(mForm, {
331
- model: props.model[modelName.value],
332
- formValue: mForm?.values,
333
- });
334
- } else if (props.config.defaultAdd) {
335
- inputs = props.config.defaultAdd;
273
+ },
274
+ });
275
+ }
276
+ };
277
+
278
+ const newHandler = async (row?: any) => {
279
+ if (props.config.max && props.model[modelName.value].length >= props.config.max) {
280
+ tMagicMessage.error(`最多新增配置不能超过${props.config.max}条`);
281
+ return;
282
+ }
283
+
284
+ const columns = props.config.items;
285
+ const enumValues = props.config.enum || [];
286
+ let enumV = [];
287
+ const { length } = props.model[modelName.value];
288
+ const key = props.config.key || 'id';
289
+ let inputs: any = {};
290
+
291
+ if (enumValues.length) {
292
+ if (length >= enumValues.length) {
293
+ return;
294
+ }
295
+ enumV = enumValues.filter((item) => {
296
+ let i = 0;
297
+ for (; i < length; i++) {
298
+ if (item[key] === props.model[modelName.value][i][key]) {
299
+ break;
336
300
  }
337
-
338
- inputs = await initValue(mForm, {
339
- config: columns,
340
- initValues: inputs,
341
- });
342
- }
343
-
344
- if (props.sortKey && length) {
345
- inputs[props.sortKey] = props.model[modelName.value][length - 1][props.sortKey] - 1;
346
301
  }
302
+ return i === length;
303
+ });
347
304
 
348
- props.model[modelName.value].push(inputs);
349
- emit('change', props.model[modelName.value]);
350
- };
351
-
352
- if (!(globalThis as any).XLSX) {
353
- asyncLoadJs('https://cdn.bootcdn.net/ajax/libs/xlsx/0.17.0/xlsx.full.min.js');
305
+ if (enumV.length > 0) {
306
+ // eslint-disable-next-line prefer-destructuring
307
+ inputs = enumV[0];
354
308
  }
355
-
356
- onMounted(() => {
357
- if (props.config.defautSort) {
358
- sortChange(props.config.defautSort);
359
- } else if (props.config.defaultSort) {
360
- sortChange(props.config.defaultSort);
361
- }
362
-
363
- if (props.sort && props.sortKey) {
364
- props.model[modelName.value].sort((a: any, b: any) => b[props.sortKey] - a[props.sortKey]);
365
- }
366
-
367
- if (props.config.dropSort) {
368
- rowDrop();
369
- }
309
+ } else if (Array.isArray(row)) {
310
+ columns.forEach((column, index) => {
311
+ column.name && (inputs[column.name] = row[index]);
370
312
  });
313
+ } else {
314
+ if (typeof props.config.defaultAdd === 'function') {
315
+ inputs = await props.config.defaultAdd(mForm, {
316
+ model: props.model[modelName.value],
317
+ formValue: mForm?.values,
318
+ });
319
+ } else if (props.config.defaultAdd) {
320
+ inputs = props.config.defaultAdd;
321
+ }
371
322
 
372
- return {
373
- mForm,
374
- pagesize,
375
- pagecontext,
376
- foreUpdate,
377
- isFullscreen,
378
- elTable,
379
- mTable,
380
- excelBtn,
381
- modelName,
382
- updateKey,
383
- ArrowDown,
384
- ArrowUp,
385
- Delete,
386
- FullScreen,
387
- Grid,
388
-
389
- data: computed(() =>
390
- props.model[modelName.value].filter(
391
- (item: any, index: number) =>
392
- index >= pagecontext.value * pagesize.value && index + 1 <= (pagecontext.value + 1) * pagesize.value,
393
- ),
394
- ),
395
- addable: computed(() => {
396
- if (!props.model[modelName.value].length) {
397
- return true;
398
- }
399
- if (typeof props.config.addable === 'function') {
400
- return props.config.addable(mForm, {
401
- model: props.model[modelName.value],
402
- formValue: mForm?.values,
403
- prop: props.prop,
404
- });
405
- }
406
- return typeof props.config.addable === 'undefined' ? true : props.config.addable;
407
- }),
408
- selection: computed(() => {
409
- if (typeof props.config.selection === 'function') {
410
- return props.config.selection(mForm, { model: props.model[modelName.value] });
411
- }
412
- return props.config.selection;
413
- }),
414
- importable: computed(() => {
415
- if (typeof props.config.importable === 'function') {
416
- return props.config.importable(mForm, {
417
- formValue: mForm?.values,
418
- model: props.model[modelName.value],
419
- });
420
- }
421
- return typeof props.config.importable === 'undefined' ? false : props.config.importable;
422
- }),
423
-
424
- sortChange,
425
-
426
- display(fuc: any) {
427
- return display(mForm, fuc, props);
428
- },
429
-
430
- itemExtra(fuc: any, index: number) {
431
- if (typeof fuc === 'function') {
432
- return fuc(mForm, {
433
- values: mForm?.initValues,
434
- model: props.model,
435
- formValue: mForm ? mForm.values : props.model,
436
- prop: props.prop,
437
- index,
438
- });
439
- }
440
-
441
- return fuc;
442
- },
443
-
444
- newHandler,
445
-
446
- removeHandler(index: number) {
447
- props.model[modelName.value].splice(index, 1);
448
- emit('change', props.model[modelName.value]);
449
- },
450
-
451
- selectHandle(selection: any, row: any) {
452
- if (typeof props.config.selection === 'string' && props.config.selection === 'single') {
453
- elTable.value?.clearSelection();
454
- elTable.value?.toggleRowSelection(row, true);
455
- }
456
- emit('select', selection, row);
457
- if (typeof props.config.onSelect === 'function') {
458
- props.config.onSelect(mForm, { selection, row, config: props.config });
459
- }
460
- },
461
-
462
- toggleRowSelection(row: any, selected: boolean) {
463
- elTable.value?.toggleRowSelection.call(elTable.value, row, selected);
464
- },
465
-
466
- makeConfig(config: ColumnConfig) {
467
- const newConfig = cloneDeep(config);
468
- delete newConfig.display;
469
- return newConfig;
470
- },
471
-
472
- upHandler(index: number) {
473
- if (timer) {
474
- clearTimeout(timer);
475
- }
476
-
477
- timer = setTimeout(() => {
478
- swapArray(index, index - 1);
479
- }, 300);
480
- },
481
-
482
- topHandler(index: number) {
483
- if (timer) {
484
- clearTimeout(timer);
485
- }
486
-
487
- // 首先判断当前元素需要上移几个位置,置底移动到数组的第一位
488
- const moveNum = index;
489
-
490
- // 循环出需要一个一个上移的次数
491
- for (let i = 0; i < moveNum; i++) {
492
- swapArray(index, index - 1);
493
- index -= 1;
494
- }
495
- },
496
-
497
- downHandler(index: number) {
498
- if (timer) {
499
- clearTimeout(timer);
500
- }
501
-
502
- timer = setTimeout(() => {
503
- swapArray(index, index + 1);
504
- }, 300);
505
- },
506
-
507
- bottomHandler(index: number) {
508
- if (timer) {
509
- clearTimeout(timer);
510
- }
511
-
512
- // 首先判断当前元素需要上移几个位置,置底移动到数组的第一位
513
- const moveNum = props.model[modelName.value].length - 1 - index;
514
-
515
- // 循环出需要一个一个上移的次数
516
- for (let i = 0; i < moveNum; i++) {
517
- swapArray(index, index + 1);
518
- index += 1;
519
- }
520
- },
521
-
522
- // 希望支持单行可控制是否显示删除按钮,不会影响现有逻辑
523
- showDelete(index: number) {
524
- const deleteFunc = props.config.delete;
525
- if (deleteFunc && typeof deleteFunc === 'function') {
526
- return deleteFunc(props.model[modelName.value], index, mForm?.values);
527
- }
528
- return true;
529
- },
530
-
531
- clearHandler() {
532
- const len = props.model[modelName.value].length;
533
- props.model[modelName.value].splice(0, len);
534
- mForm?.$emit('field-change', props.prop, props.model[modelName.value]);
535
- },
536
-
537
- excelHandler(file: UploadFile) {
538
- if (!file || !file.raw) {
539
- return false;
540
- }
541
- const reader = new FileReader();
542
- reader.onload = () => {
543
- const data = reader.result;
544
- const pdata = (globalThis as any).XLSX.read(data, { type: 'array' });
545
- pdata.SheetNames.forEach((sheetName: string) => {
546
- const arr = (globalThis as any).XLSX.utils.sheet_to_json(pdata.Sheets[sheetName], { header: 1 });
547
- if (arr?.[0]) {
548
- arr.forEach((row: any) => {
549
- newHandler(row);
550
- });
551
- }
552
- setTimeout(() => {
553
- excelBtn.value?.clearFiles();
554
- }, 300);
555
- });
556
- };
557
- reader.readAsArrayBuffer(file.raw);
558
-
559
- return false;
560
- },
323
+ inputs = await initValue(mForm, {
324
+ config: columns,
325
+ initValues: inputs,
326
+ });
327
+ }
328
+
329
+ if (props.sortKey && length) {
330
+ inputs[props.sortKey] = props.model[modelName.value][length - 1][props.sortKey] - 1;
331
+ }
332
+
333
+ props.model[modelName.value].push(inputs);
334
+ emit('change', props.model[modelName.value]);
335
+ };
336
+
337
+ if (!(globalThis as any).XLSX) {
338
+ asyncLoadJs('https://cdn.bootcdn.net/ajax/libs/xlsx/0.17.0/xlsx.full.min.js');
339
+ }
340
+
341
+ onMounted(() => {
342
+ if (props.config.defautSort) {
343
+ sortChange(props.config.defautSort);
344
+ } else if (props.config.defaultSort) {
345
+ sortChange(props.config.defaultSort);
346
+ }
347
+
348
+ if (props.sort && props.sortKey) {
349
+ props.model[modelName.value].sort((a: any, b: any) => b[props.sortKey] - a[props.sortKey]);
350
+ }
351
+
352
+ if (props.config.dropSort) {
353
+ rowDrop();
354
+ }
355
+ });
561
356
 
562
- handleSizeChange(val: number) {
563
- pagesize.value = val;
564
- },
357
+ const addable = computed(() => {
358
+ if (!props.model[modelName.value].length) {
359
+ return true;
360
+ }
361
+ if (typeof props.config.addable === 'function') {
362
+ return props.config.addable(mForm, {
363
+ model: props.model[modelName.value],
364
+ formValue: mForm?.values,
365
+ prop: props.prop,
366
+ });
367
+ }
368
+ return typeof props.config.addable === 'undefined' ? true : props.config.addable;
369
+ });
565
370
 
566
- handleCurrentChange(val: number) {
567
- pagecontext.value = val - 1;
568
- },
371
+ const selection = computed(() => {
372
+ if (typeof props.config.selection === 'function') {
373
+ return props.config.selection(mForm, { model: props.model[modelName.value] });
374
+ }
375
+ return props.config.selection;
376
+ });
569
377
 
570
- toggleMode() {
571
- const calcLabelWidth = (label: string) => {
572
- if (!label) return '0px';
573
- const zhLength = label.match(/[^\x00-\xff]/g)?.length || 0;
574
- const chLength = label.length - zhLength;
575
- return `${Math.max(chLength * 8 + zhLength * 20, 80)}px`;
576
- };
577
-
578
- // 切换为groupList的形式
579
- props.config.type = 'groupList';
580
- props.config.enableToggleMode = true;
581
- props.config.tableItems = props.config.items;
582
- props.config.items =
583
- props.config.groupItems ||
584
- props.config.items.map((item: any) => {
585
- const text = item.text || item.label;
586
- const labelWidth = calcLabelWidth(text);
587
- return {
588
- ...item,
589
- text,
590
- labelWidth,
591
- span: item.span || 12,
592
- };
593
- });
594
- },
378
+ const importable = computed(() => {
379
+ if (typeof props.config.importable === 'function') {
380
+ return props.config.importable(mForm, {
381
+ formValue: mForm?.values,
382
+ model: props.model[modelName.value],
383
+ });
384
+ }
385
+ return typeof props.config.importable === 'undefined' ? false : props.config.importable;
386
+ });
595
387
 
596
- toggleFullscreen() {
597
- if (isFullscreen.value) {
598
- mTable.value?.classList.remove('fixed');
599
- isFullscreen.value = false;
600
- } else {
601
- mTable.value?.classList.add('fixed');
602
- isFullscreen.value = true;
603
- }
604
- },
388
+ const display = (fuc: any) => displayFunc(mForm, fuc, props);
605
389
 
606
- getProp(index: number) {
607
- const { prop } = toRefs(props);
608
- return `${prop.value}${prop.value ? '.' : ''}${index + 1 + pagecontext.value * pagesize.value - 1}`;
609
- },
610
- };
611
- },
390
+ const itemExtra = (fuc: any, index: number) => {
391
+ if (typeof fuc === 'function') {
392
+ return fuc(mForm, {
393
+ values: mForm?.initValues,
394
+ model: props.model,
395
+ formValue: mForm ? mForm.values : props.model,
396
+ prop: props.prop,
397
+ index,
398
+ });
399
+ }
400
+
401
+ return fuc;
402
+ };
403
+
404
+ const removeHandler = (index: number) => {
405
+ props.model[modelName.value].splice(index, 1);
406
+ emit('change', props.model[modelName.value]);
407
+ };
408
+
409
+ const selectHandle = (selection: any, row: any) => {
410
+ if (typeof props.config.selection === 'string' && props.config.selection === 'single') {
411
+ tMagicTable.value?.clearSelection();
412
+ tMagicTable.value?.toggleRowSelection(row, true);
413
+ }
414
+ emit('select', selection, row);
415
+ if (typeof props.config.onSelect === 'function') {
416
+ props.config.onSelect(mForm, { selection, row, config: props.config });
417
+ }
418
+ };
419
+
420
+ const toggleRowSelection = (row: any, selected: boolean) => {
421
+ tMagicTable.value?.toggleRowSelection.call(tMagicTable.value, row, selected);
422
+ };
423
+
424
+ const makeConfig = (config: ColumnConfig) => {
425
+ const newConfig = cloneDeep(config);
426
+ delete newConfig.display;
427
+ return newConfig;
428
+ };
429
+
430
+ const upHandler = (index: number) => {
431
+ if (timer) {
432
+ clearTimeout(timer);
433
+ }
434
+
435
+ timer = setTimeout(() => {
436
+ swapArray(index, index - 1);
437
+ }, 300);
438
+ };
439
+
440
+ const topHandler = (index: number) => {
441
+ if (timer) {
442
+ clearTimeout(timer);
443
+ }
444
+
445
+ // 首先判断当前元素需要上移几个位置,置底移动到数组的第一位
446
+ const moveNum = index;
447
+
448
+ // 循环出需要一个一个上移的次数
449
+ for (let i = 0; i < moveNum; i++) {
450
+ swapArray(index, index - 1);
451
+ index -= 1;
452
+ }
453
+ };
454
+
455
+ const downHandler = (index: number) => {
456
+ if (timer) {
457
+ clearTimeout(timer);
458
+ }
459
+
460
+ timer = setTimeout(() => {
461
+ swapArray(index, index + 1);
462
+ }, 300);
463
+ };
464
+
465
+ const bottomHandler = (index: number) => {
466
+ if (timer) {
467
+ clearTimeout(timer);
468
+ }
469
+
470
+ // 首先判断当前元素需要上移几个位置,置底移动到数组的第一位
471
+ const moveNum = props.model[modelName.value].length - 1 - index;
472
+
473
+ // 循环出需要一个一个上移的次数
474
+ for (let i = 0; i < moveNum; i++) {
475
+ swapArray(index, index + 1);
476
+ index += 1;
477
+ }
478
+ };
479
+
480
+ // 希望支持单行可控制是否显示删除按钮,不会影响现有逻辑
481
+ const showDelete = (index: number) => {
482
+ const deleteFunc = props.config.delete;
483
+ if (deleteFunc && typeof deleteFunc === 'function') {
484
+ return deleteFunc(props.model[modelName.value], index, mForm?.values);
485
+ }
486
+ return true;
487
+ };
488
+
489
+ const clearHandler = () => {
490
+ const len = props.model[modelName.value].length;
491
+ props.model[modelName.value].splice(0, len);
492
+ mForm?.$emit('field-change', props.prop, props.model[modelName.value]);
493
+ };
494
+
495
+ const excelHandler = (file: any) => {
496
+ if (!file || !file.raw) {
497
+ return false;
498
+ }
499
+ const reader = new FileReader();
500
+ reader.onload = () => {
501
+ const data = reader.result;
502
+ const pdata = (globalThis as any).XLSX.read(data, { type: 'array' });
503
+ pdata.SheetNames.forEach((sheetName: string) => {
504
+ const arr = (globalThis as any).XLSX.utils.sheet_to_json(pdata.Sheets[sheetName], { header: 1 });
505
+ if (arr?.[0]) {
506
+ arr.forEach((row: any) => {
507
+ newHandler(row);
508
+ });
509
+ }
510
+ setTimeout(() => {
511
+ excelBtn.value?.clearFiles();
512
+ }, 300);
513
+ });
514
+ };
515
+ reader.readAsArrayBuffer(file.raw);
516
+
517
+ return false;
518
+ };
519
+
520
+ const handleSizeChange = (val: number) => {
521
+ pagesize.value = val;
522
+ };
523
+
524
+ const handleCurrentChange = (val: number) => {
525
+ pagecontext.value = val - 1;
526
+ };
527
+
528
+ const toggleMode = () => {
529
+ const calcLabelWidth = (label: string) => {
530
+ if (!label) return '0px';
531
+ const zhLength = label.match(/[^\x00-\xff]/g)?.length || 0;
532
+ const chLength = label.length - zhLength;
533
+ return `${Math.max(chLength * 8 + zhLength * 20, 80)}px`;
534
+ };
535
+
536
+ // 切换为groupList的形式
537
+ props.config.type = 'groupList';
538
+ props.config.enableToggleMode = true;
539
+ props.config.tableItems = props.config.items;
540
+ props.config.items =
541
+ props.config.groupItems ||
542
+ props.config.items.map((item: any) => {
543
+ const text = item.text || item.label;
544
+ const labelWidth = calcLabelWidth(text);
545
+ return {
546
+ ...item,
547
+ text,
548
+ labelWidth,
549
+ span: item.span || 12,
550
+ };
551
+ });
552
+ };
553
+
554
+ const toggleFullscreen = () => {
555
+ if (isFullscreen.value) {
556
+ mTable.value?.classList.remove('fixed');
557
+ isFullscreen.value = false;
558
+ } else {
559
+ mTable.value?.classList.add('fixed');
560
+ isFullscreen.value = true;
561
+ }
562
+ };
563
+
564
+ const getProp = (index: number) => {
565
+ const { prop } = toRefs(props);
566
+ return `${prop.value}${prop.value ? '.' : ''}${index + 1 + pagecontext.value * pagesize.value - 1}`;
567
+ };
568
+
569
+ defineExpose({
570
+ toggleRowSelection,
612
571
  });
613
572
  </script>