@vue-ui-kit/ant 1.7.4 → 1.8.2

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.
@@ -1,9 +1,10 @@
1
1
  <script lang="ts" generic="F = Recordable" setup name="PFormGroup">
2
- import { computed, nextTick, PropType, ref, watchEffect } from 'vue';
2
+ import { computed, nextTick, PropType, ref, watch, watchEffect } from 'vue';
3
3
  import { PFormGroupProps, PFormBlockInstance } from '#/antProxy';
4
4
  import { MoreOutlined } from '@ant-design/icons-vue';
5
+ import type { Tabs } from 'ant-design-vue'
5
6
  import { Form } from 'ant-design-vue'
6
- import { cloneDeep, toString, isFunction, omit, maxBy, debounce } from 'lodash-es';
7
+ import { clone, toString, isFunction, omit, max, debounce } from 'xe-utils';
7
8
  import PGroupBlock from '@/components/PGroupBlock.vue';
8
9
  import {
9
10
  Card as ACard,
@@ -19,25 +20,28 @@
19
20
  import { $warning } from '@/hooks/useMessage';
20
21
 
21
22
  const useForm = Form.useForm
23
+ const tabsRef = ref<InstanceType<typeof Tabs>>()
22
24
  const props = defineProps<PFormGroupProps<F>>();
25
+ const rootRef = ref<InstanceType<typeof ACard>>()
23
26
  const model = defineModel({
24
27
  type: Array as PropType<Partial<F & { __index: number }>[]>,
25
28
  default: () => [],
26
29
  });
27
30
  const activeKey = ref(0);
31
+ const error_indexes = ref<number[]>([])
28
32
  const blockInstance = ref<PFormBlockInstance[]>([]);
29
33
  const setActiveKey = (key: number) => {
30
34
  activeKey.value = key;
31
35
  };
32
36
  const maxLen = computed(() => props.max ?? Infinity);
33
37
  const handleAddItem = (idx: number) => {
34
- const creator = props.creatItem ?? (() => Promise.resolve({} as Partial<F>));
38
+ const creator = props.createItem ?? (() => Promise.resolve({} as Partial<F>));
35
39
  creator({ list: model.value }).then((item) => {
36
40
  model.value = [
37
41
  ...model.value,
38
42
  {
39
43
  ...item,
40
- __index: (maxBy(model.value, (m) => m.__index ?? -1)?.__index ?? -1) + 1,
44
+ __index: (max(model.value, (m) => m.__index ?? -1)?.__index ?? -1) + 1,
41
45
  } as Partial<F & { __index: number }>,
42
46
  ];
43
47
  activeKey.value = idx;
@@ -47,26 +51,34 @@
47
51
  { content: '复制', code: 'copy' },
48
52
  { content: '删除', code: 'delete' },
49
53
  ];
54
+ const getPopupContainer = () => rootRef.value?.$el ?? document.body
50
55
  // 实际是否强制渲染
51
56
  const fr = computed(() => {
52
57
  return props.forceRender || model.value.length <= 5
53
58
  })
59
+ const handleBlockFocus = (idx: number) => {
60
+ const target_index = model.value.find((f, index) => index === idx)?.__index
61
+ if (valued(target_index)) {
62
+ error_indexes.value = error_indexes.value.filter(f => f !== target_index)
63
+ }
64
+ }
54
65
  const handleTabChange = () => {
55
66
  nextTick().then(() => {
67
+ handleBlockFocus(activeKey.value)
56
68
  blockInstance.value[activeKey.value]?.$form?.validate()
57
69
  })
58
70
  }
59
- watchEffect(() => {
60
- if (!props.keepSerial) {
61
- const unSortItems = model.value.filter((f) => !valued(f.__index));
62
- if (unSortItems.length > 0) {
63
- unSortItems.forEach((item) => {
64
- // @ts-ignore
65
- item.__index = (maxBy(model.value, (m) => m.__index ?? -1)?.__index ?? -1) + 1;
66
- });
67
- }
71
+ watch(() => model.value, () => {
72
+ if (!props.keepSerial) {
73
+ const unSortItems = model.value.filter(f => !valued(f.__index))
74
+ if (unSortItems.length > 0) {
75
+ unSortItems.forEach((item) => {
76
+ // @ts-ignore
77
+ item.__index = (max(model.value, m => m.__index ?? -1)?.__index ?? -1) + 1
78
+ })
68
79
  }
69
- });
80
+ }
81
+ }, { immediate: true })
70
82
  const handleMenu = ({ key }: MenuInfo, item: Partial<F & { __index: number }>, idx: number) => {
71
83
  if (props.menuHandler && isFunction(props.menuHandler)) {
72
84
  props.menuHandler({ code: toString(key), data: item, index: idx });
@@ -88,9 +100,9 @@
88
100
  }
89
101
  model.value = [
90
102
  ...model.value,
91
- cloneDeep({
103
+ clone({
92
104
  ...omit(item, ['id', '__index']),
93
- __index: (maxBy(model.value, (m) => m.__index ?? -1)?.__index ?? -1) + 1,
105
+ __index: (max(model.value, (m) => m.__index ?? -1)?.__index ?? -1) + 1,
94
106
  }),
95
107
  ] as Partial<F & { __index: number }>[];
96
108
  break;
@@ -105,26 +117,74 @@
105
117
  activeKey.value = model.value.length - 1;
106
118
  }
107
119
  });
120
+
121
+ const debounceHandleBlockFocus = debounce(handleBlockFocus, 50)
122
+ watchEffect(() => {
123
+ const errorKeys = model.value.map((m, idx) => error_indexes.value.includes(m.__index!) ? idx : undefined).filter(valued)
124
+ const rootDom = tabsRef.value?.$el
125
+ if (rootDom) {
126
+ const tabPanel = rootDom.querySelectorAll(':scope >.ant-tabs-nav>.ant-tabs-nav-wrap>.ant-tabs-nav-list>.ant-tabs-tab>.ant-tabs-tab-btn')
127
+ tabPanel.forEach((tab, idx) => {
128
+ if (errorKeys.includes(idx)) {
129
+ tab.classList.add('p-error-group-tab')
130
+ }
131
+ else {
132
+ tab.classList.remove('p-error-group-tab')
133
+ }
134
+ })
135
+ }
136
+ })
108
137
  defineExpose({
109
138
  activeKey: computed(() => activeKey.value),
110
139
  setActiveKey,
111
140
  validateAll: () => {
112
- return Promise.all(blockInstance.value.map((block, idx) =>
113
- fr.value ? (block.$form?.validate() ?? Promise.resolve()) : (useForm(model.value[idx], props.getFormSetting(model.value[idx]).rules)?.validate() ?? Promise.resolve()),
114
- ))
115
- },
116
- validate: (__index: number) => {
117
- const index = model.value.findIndex(f => f.__index === __index)
118
- return fr.value
141
+ const promiseList = fr.value
142
+ ? blockInstance.value.map(block => block.$form?.validate())
143
+ : model.value.map(m => useForm(m, props.getFormSetting(m).rules)?.validate() ?? Promise.resolve())
144
+ return Promise.allSettled(promiseList).then((results) => {
145
+ // 更新 error_indexes
146
+ error_indexes.value = results
147
+ .map((res, idx) => (res.status === 'rejected' && typeof model.value[idx]?.__index === 'number' ? model.value[idx].__index as number : undefined))
148
+ .filter((v): v is number => typeof v === 'number')
149
+ if (!props.lazyErrorMark && error_indexes.value.length) {
150
+ // 跳到第一个出错的tab
151
+ const firstErrorIndex = error_indexes.value[0]
152
+ const firstErrorTab = model.value.findIndex(f => f.__index === firstErrorIndex)
153
+ if (firstErrorTab !== -1) {
154
+ activeKey.value = firstErrorTab
155
+ }
156
+ }
157
+ // 判断是否有错误
158
+ if (error_indexes.value.length) {
159
+ return Promise.reject({ error_indexes: error_indexes.value, results })
160
+ }
161
+ return Promise.resolve(results)
162
+ })
163
+ },
164
+ validate: async (__index: number) => {
165
+ const index = model.value.findIndex(f => f.__index === __index)
166
+ try {
167
+ await (fr.value
119
168
  ? (blockInstance.value[index]?.$form?.validate() ?? Promise.resolve())
120
- : (useForm(model.value[index], props.getFormSetting(model.value[index]).rules)?.validate() ?? Promise.resolve())
121
- },
169
+ : (useForm(model.value[index], props.getFormSetting(model.value[index]).rules)?.validate() ?? Promise.resolve()))
170
+ // 校验通过,移除error_indexes中的__index
171
+ error_indexes.value = error_indexes.value.filter(f => f !== __index)
172
+ return Promise.resolve()
173
+ }
174
+ catch (e) {
175
+ // 校验失败,加入error_indexes
176
+ if (!error_indexes.value.includes(__index)) {
177
+ error_indexes.value = [...error_indexes.value, __index]
178
+ }
179
+ return Promise.reject(e)
180
+ }
181
+ },
122
182
  });
123
183
  </script>
124
184
  <template>
125
- <a-card :title="title" size="small">
185
+ <a-card ref="rootRef" :title="title" size="small">
126
186
  <a-spin v-if="loading" class="w-full" />
127
- <a-tabs v-else type="editable-card" v-model:activeKey="activeKey" hide-add @change="handleTabChange">
187
+ <a-tabs v-else ref="tabsRef" type="editable-card" v-model:activeKey="activeKey" hide-add @change="handleTabChange">
128
188
  <template #rightExtra>
129
189
  <slot name="rightExtra">
130
190
  <a-button
@@ -143,7 +203,7 @@
143
203
  :force-render="fr"
144
204
  >
145
205
  <template #closeIcon>
146
- <a-dropdown v-if="editAble && itemMenus?.length">
206
+ <a-dropdown v-if="editAble && itemMenus?.length" :get-popup-container="getPopupContainer">
147
207
  <MoreOutlined />
148
208
  <template #overlay>
149
209
  <a-menu @click="(e) => debounceHandleMenu(e, item, idx)">
@@ -173,6 +233,8 @@
173
233
  :key="idx"
174
234
  :source="item"
175
235
  :get-form-setting="getFormSetting"
236
+ @focus.capture="debounceHandleBlockFocus(idx)"
237
+ @click.capture="debounceHandleBlockFocus(idx)"
176
238
  />
177
239
  </a-tab-pane>
178
240
  </a-tabs>
@@ -11,32 +11,41 @@
11
11
  toRefs,
12
12
  onBeforeUnmount,
13
13
  } from 'vue';
14
- import { debounce, get, isArray, isBoolean, isFunction, isObject, isString, merge, omit, toNumber } from 'lodash-es';
14
+ import { debounce, get, isArray, isBoolean, isFunction, isObject, isString, merge, omit, toNumber } from 'xe-utils';
15
15
  import { eachTree } from '@/utils/treeHelper';
16
16
  import { message as $message } from 'ant-design-vue';
17
- import RenderAntItem from '@/components/RenderAntItem';
18
17
  import RenderTitleSlots from '@/components/RenderTitleSlots';
19
18
  import RenderDefaultSlots from '@/components/RenderDefaultSlots';
20
19
  import { v4 as uuid_v4 } from 'uuid';
21
- import { isGoodValue, valued } from '@/utils/is';
22
- import RenderItemSlots from '@/components/RenderItemSlots';
23
- import { cleanCol, defaultItemResponsive, defaultLabelCol } from '@/utils/core';
20
+ import { isGoodValue } from '@/utils/is';
21
+ import PFormCol from '@/components/PFormCol.vue';
22
+ import { cleanCol, defaultLabelCol } from '@/utils/core';
23
+ import { getGridDefaults } from '@/utils/config';
24
24
  import Icon from '@/renders/Icon';
25
25
  import { $confirm } from '@/hooks/useMessage';
26
26
  import {
27
27
  Table as ATable,
28
28
  Button as AButton,
29
29
  Form as AForm,
30
- FormItem as AFormItem,
31
30
  Row as ARow,
32
- Col as ACol,
33
31
  Spin as ASpin,
34
- Tooltip as ATooltip,
35
32
  } from 'ant-design-vue';
36
33
  import { TablePaginationConfig } from 'ant-design-vue/es/table/interface';
37
- import { InfoCircleOutlined, DownOutlined } from '@ant-design/icons-vue';
34
+ import { DownOutlined } from '@ant-design/icons-vue';
38
35
 
39
36
  const props = defineProps<PGridProps<D, F>>();
37
+
38
+ // 应用默认值
39
+ const gridDefaults = getGridDefaults();
40
+ const propsWithDefaults = computed(() => ({
41
+ ...props,
42
+ rowKey: props.rowKey ?? 'id',
43
+ scrollMode: props.scrollMode ?? 'inner',
44
+ align: props.align ?? gridDefaults.align ?? 'left',
45
+ lazyReset: props.lazyReset ?? gridDefaults.lazyReset ?? false,
46
+ fitHeight: props.fitHeight ?? gridDefaults.fitHeight ?? 170,
47
+ }));
48
+
40
49
  const {
41
50
  formConfig,
42
51
  pageConfig,
@@ -63,7 +72,6 @@
63
72
  loading.toolbar = value;
64
73
  }
65
74
  };
66
- const submitOnReset = true;
67
75
  const boxEl = ref<HTMLDivElement>();
68
76
  const pFormWrapper = ref<HTMLDivElement>();
69
77
  const renderHeight = ref(500);
@@ -118,9 +126,7 @@
118
126
  const tableEl = ref();
119
127
  const renderFormKey = ref(uuid_v4());
120
128
  const renderTableKey = ref(uuid_v4());
121
- const refreshForm = () => {
122
- renderFormKey.value = uuid_v4();
123
- };
129
+
124
130
  const codeLoadings = reactive<Record<string, boolean>>(
125
131
  [
126
132
  ...(props.toolbarConfig?.buttons?.map((m) => m.code) ?? []).filter((f) => f),
@@ -139,7 +145,6 @@
139
145
  const refreshTable = () => {
140
146
  renderTableKey.value = uuid_v4();
141
147
  };
142
- const debounceRefreshForm = debounce(refreshForm, 100);
143
148
  const debounceRefreshTable = debounce(refreshTable, 100);
144
149
  const slotDefaultColumns = computed(() => {
145
150
  const cols: ColumnProps<D>[] = [];
@@ -225,11 +230,18 @@
225
230
  obj[item.field] = undefined;
226
231
  }
227
232
  }
233
+ else if (item.field && item.slots) {
234
+ if (isGoodValue(item.slots.defaultValue)) {
235
+ obj[item.field] = item.slots.defaultValue
236
+ }
237
+ else {
238
+ obj[item.field] = undefined
239
+ }
240
+ }
228
241
  });
229
242
  queryFormData.value = obj;
230
243
  }
231
244
  emit('resetQuery');
232
- refreshForm();
233
245
  }
234
246
 
235
247
  pagination.page = 1;
@@ -266,6 +278,8 @@
266
278
  };
267
279
  const enoughSpacing = ref(true);
268
280
  const reload = () => {
281
+ selectedCaches.value = []
282
+ selectedRowKeys.value = []
269
283
  return resetQueryFormData();
270
284
  };
271
285
  const resetPage = () => {
@@ -387,13 +401,6 @@
387
401
  resetPage();
388
402
  };
389
403
 
390
- watch(
391
- () => formConfig.value,
392
- () => {
393
- debounceRefreshForm();
394
- },
395
- { deep: true },
396
- );
397
404
  watch(
398
405
  () => [columns.value, proxyConfig.value, toolbarConfig.value],
399
406
  () => {
@@ -413,7 +420,7 @@
413
420
  const showCountHeight = selectConfig.value?.showCount ? 22 : 0
414
421
  renderHeight.value =
415
422
  props.renderY ??
416
- toNumber(ph.replace('px', '')) -(props.fitHeight ?? 170) -(!!props.toolbarConfig ? 30 : 0) -formHeight- showCountHeight;
423
+ toNumber(ph.replace('px', '')) -propsWithDefaults.value.fitHeight -(props.toolbarConfig ? 30 : 0) -formHeight- showCountHeight;
417
424
  enoughSpacing.value = toNumber(ph.replace('px', '')) > 600;
418
425
  };
419
426
  defineExpose({
@@ -428,6 +435,7 @@
428
435
  setBtnLoading,
429
436
  selectedRecords,
430
437
  $form: computed(() => formEl.value),
438
+ getFormData: () => queryFormData.value,
431
439
  setLoadings,
432
440
  resizeTable,
433
441
  });
@@ -457,7 +465,7 @@
457
465
  const passFields = ['align']
458
466
  const passDefaultColumnProps = (columns: ColumnProps<D>[]) => columns.map(c => ({
459
467
  ...passFields.reduce((prev, cur) => ({
460
- [cur]: props[cur],
468
+ [cur]: propsWithDefaults.value[cur],
461
469
  }), {} as ColumnProps<D>),
462
470
  ...c,
463
471
  }))
@@ -484,64 +492,13 @@
484
492
  @submit="handleFormSubmit"
485
493
  >
486
494
  <a-row :gutter="[6, 12]">
487
- <a-col
495
+ <p-form-col
488
496
  v-for="(item, idx) in formConfig!.items"
489
- :key="'_col_' + idx"
490
- v-bind="item.col ?? (item.span ? { span: item.span } : defaultItemResponsive)"
491
- >
492
- <a-form-item
493
- :key="'_item_' + idx"
494
- :class="`p-content-align-${item.align ?? 'left'} ${item.forceRequired ? 'p-required' : ''}`"
495
- :label="item.title"
496
- :name="item.field"
497
- v-bind="
498
- omit(item, [
499
- 'field',
500
- 'title',
501
- 'span',
502
- 'col',
503
- 'itemRender',
504
- 'forceRequired',
505
- 'tooltip',
506
- ])
507
- "
508
- >
509
- <render-item-slots
510
- v-if="item.slots?.default"
511
- :key="'_sl_' + (item.field ?? '_') + '_' + idx"
512
- :form-data="queryFormData"
513
- :item="item"
514
- :pass-trigger="() => {}"
515
- :pass-delay-trigger="() => {}"
516
- />
517
- <render-ant-item
518
- v-else-if="item.itemRender?.name"
519
- :key="'_re_' + (item.field ?? '_') + '_' + idx"
520
- :default-handler="{
521
- reset: () => {
522
- resetQueryFormData(!submitOnReset);
523
- },
524
- }"
525
- :item-render="item.itemRender"
526
- :render-form-params="{ data: queryFormData, field: item.field }"
527
- />
528
- <span v-else></span>
529
- <template #tooltip v-if="item.tooltipConfig">
530
- <a-tooltip
531
- v-if="isFunction(item.tooltipConfig.title)"
532
- v-bind="omit(item.tooltipConfig, ['title'])"
533
- >
534
- <InfoCircleOutlined class="cursor-pointer py-4x px-2x" />
535
- <template #title>
536
- <div v-html="item.tooltipConfig.title()"></div>
537
- </template>
538
- </a-tooltip>
539
- <a-tooltip v-else v-bind="item.tooltipConfig">
540
- <InfoCircleOutlined class="cursor-pointer py-4x px-2x" />
541
- </a-tooltip>
542
- </template>
543
- </a-form-item>
544
- </a-col>
497
+ :key="`_col_${idx}`"
498
+ :form-data="queryFormData"
499
+ :item="item as PFormItemProps<Partial<F>>"
500
+ @reset="resetQueryFormData(propsWithDefaults.lazyReset)"
501
+ />
545
502
  </a-row>
546
503
  </a-form>
547
504
  </a-spin>
@@ -4,7 +4,7 @@
4
4
  import { ColumnProps } from '#/antProxy';
5
5
  import { cleanCol } from '@/utils/core';
6
6
  import RenderDefaultSlots from '@/components/RenderDefaultSlots';
7
- import { merge } from 'lodash-es';
7
+ import { merge } from 'xe-utils';
8
8
 
9
9
  const props = defineProps({
10
10
  modelValue: {
@@ -21,7 +21,7 @@ import {
21
21
  TimePicker,
22
22
  TreeSelect,
23
23
  } from 'ant-design-vue';
24
- import { set, isFunction, merge, omit } from 'lodash-es';
24
+ import { set, isFunction, merge, omit } from 'xe-utils';
25
25
  import { ButtonProps } from 'ant-design-vue/lib/button';
26
26
  import { isBadValue, isGoodValue, noValue, valued } from '@/utils/is';
27
27
  import TableInput from '@/renders/TableInput.vue';
@@ -99,7 +99,37 @@
99
99
  .p-form-wrapper {
100
100
  z-index: 4;
101
101
  }
102
-
102
+ .p-error-hang-out {
103
+ .ant-input-affix-wrapper-status-error:not(
104
+ .ant-input-affix-wrapper-disabled
105
+ ):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper {
106
+ border-color: #d9d9d9 !important;
107
+
108
+ &:focus {
109
+ border-color: #4096ff !important;
110
+ }
111
+ }
112
+ .ant-form-item-explain-error {
113
+ opacity: 0 !important;
114
+ transform: translateY(-10px) !important;
115
+ max-height: 0 !important;
116
+ overflow: hidden !important;
117
+ transition: none !important;
118
+ }
119
+ }
120
+ .ant-form-item-explain-error {
121
+ opacity: 0;
122
+ transform: translateY(-10px);
123
+ max-height: 0;
124
+ overflow: hidden;
125
+ transition: opacity 0.3s ease-out 0.3s, transform 0.3s ease-out 0.3s,
126
+ max-height 0.3s ease-out 0.3s;
127
+ }
128
+ .ant-form-item-has-error .ant-form-item-explain-error {
129
+ opacity: 1;
130
+ transform: translateY(0);
131
+ max-height: 100px;
132
+ }
103
133
  .p-toolbar-wrapper {
104
134
  box-shadow: 0 8px #fff;
105
135
  border-radius: 0.5em 0.5em 0 0;
@@ -204,7 +234,42 @@
204
234
  }
205
235
  }
206
236
  }
237
+ .p-error-group-tab{
238
+ position:relative;
239
+ overflow: visible;
240
+ color:#f5222d!important;
241
+ &:after{
242
+ content:'🏷️';
243
+ position:absolute;
244
+ top:-1em;
245
+ right:0;
246
+ width:1em;
247
+ height:1em;
248
+ font-size:0.8em;
249
+ animation: heartbeat 2s infinite;
250
+ }
251
+ }
252
+ .p-error-hang-out {
253
+ .ant-input-affix-wrapper-status-error:not(
254
+ .ant-input-affix-wrapper-disabled
255
+ ):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper {
256
+ border-color: #d9d9d9 !important;
257
+
258
+ &:focus {
259
+ border-color: #4096ff !important;
260
+ }
261
+ }
262
+ .ant-form-item-explain-error {
263
+ display: none;
264
+ }
265
+ }
266
+ .no-error-border {
267
+ border-color: #d9d9d9 !important;
207
268
 
269
+ &:focus {
270
+ border-color: #4096ff !important;
271
+ }
272
+ }
208
273
  //endregion
209
274
 
210
275
  @each $align in right center {
@@ -220,3 +285,17 @@
220
285
  text-align: #{$align};
221
286
  }
222
287
  }
288
+
289
+ @keyframes heartbeat {
290
+ 0% { transform: scale(1); }
291
+ 6% { transform: scale(1.22); }
292
+ 12% { transform: scale(1); }
293
+ 18% { transform: scale(1.18); }
294
+ 24% { transform: scale(1); }
295
+ 48% { transform: scale(1); } // 长停顿
296
+ 54% { transform: scale(1.22); }
297
+ 60% { transform: scale(1); }
298
+ 66% { transform: scale(1.18); }
299
+ 72% { transform: scale(1); }
300
+ 100% { transform: scale(1); } // 长停顿
301
+ }
@@ -1,4 +1,4 @@
1
- import { isArray, isFunction, isString, toNumber } from 'lodash-es';
1
+ import { isArray, isFunction, isString, toNumber } from 'xe-utils';
2
2
  import { valued } from '@/utils/is';
3
3
  import { CellFuncArg, ColumnProps } from '#/antProxy';
4
4
 
@@ -0,0 +1,72 @@
1
+ import { PFormProps, PGridProps } from '#/antProxy';
2
+ import { clone } from 'xe-utils';
3
+
4
+ // 全局配置接口
5
+ export interface UIKitConfig {
6
+ form?: {
7
+ labelCol?: any;
8
+ wrapperCol?: any;
9
+ };
10
+ grid?: {
11
+ align?: 'left' | 'right' | 'center';
12
+ lazyReset?: boolean;
13
+ fitHeight?: number;
14
+ };
15
+ }
16
+
17
+ // 默认配置
18
+ const defaultConfig: UIKitConfig = {
19
+ form: {
20
+ labelCol: { span: 6 },
21
+ wrapperCol: { span: 16 },
22
+ },
23
+ grid: {
24
+ align: 'left',
25
+ lazyReset: false,
26
+ fitHeight: 170,
27
+ },
28
+ };
29
+
30
+ // 当前配置(可被修改)
31
+ let currentConfig: UIKitConfig = clone(defaultConfig);
32
+
33
+ // 设置配置
34
+ export function setUIKitConfig(config: Partial<UIKitConfig>): void {
35
+ currentConfig = {
36
+ form: {
37
+ ...currentConfig.form,
38
+ ...config.form,
39
+ },
40
+ grid: {
41
+ ...currentConfig.grid,
42
+ ...config.grid,
43
+ },
44
+ };
45
+ }
46
+
47
+ // 获取配置
48
+ export function getUIKitConfig(): UIKitConfig {
49
+ return currentConfig;
50
+ }
51
+
52
+ // 获取表单默认配置
53
+ export function getFormDefaults(): Partial<PFormProps> {
54
+ return {
55
+ labelCol: currentConfig.form?.labelCol,
56
+ wrapperCol: currentConfig.form?.wrapperCol,
57
+ };
58
+ }
59
+
60
+ // 获取Grid默认配置
61
+ export function getGridDefaults(): Partial<PGridProps> {
62
+ return {
63
+ align: currentConfig.grid?.align,
64
+ lazyReset: currentConfig.grid?.lazyReset,
65
+ fitHeight: currentConfig.grid?.fitHeight,
66
+ };
67
+ }
68
+
69
+ // 重置为默认配置
70
+ export function resetUIKitConfig(): void {
71
+ currentConfig = JSON.parse(JSON.stringify(defaultConfig));
72
+ }
@@ -1,6 +1,6 @@
1
1
  import { ColumnProps, Responsive } from '#/antProxy';
2
2
  import { TableColumnGroupType, TableColumnType } from 'ant-design-vue';
3
- import { isArray, isNumber, omit, zipObject } from 'lodash-es';
3
+ import { isArray, isNumber, omit, zipObject } from 'xe-utils';
4
4
  import { valued } from '@/utils/is';
5
5
 
6
6
  export const cleanCol = (col: ColumnProps): TableColumnType | TableColumnGroupType<Recordable> => {