@vue-ui-kit/ant 1.2.0 → 1.3.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.
@@ -1,277 +1,279 @@
1
1
  <script generic="D = Recordable, F = Recordable" lang="ts" name="PGrid" setup>
2
- import { ColumnProps, PFormItemProps, PGridProps, ResponsePathConfig } from '#/antProxy'
3
- import { computed, useAttrs, ref, Ref, reactive, onMounted, watch, toRefs } from 'vue'
4
- import { debounce, get, isArray, isFunction, isString, merge, omit, toNumber } from 'lodash-es'
5
- import { eachTree } from '@/utils/treeHelper'
6
- import { message as $message } from 'ant-design-vue'
7
- import RenderAntItem from '@/components/RenderAntItem'
8
- import RenderTitleSlots from '@/components/RenderTitleSlots'
9
- import RenderDefaultSlots from '@/components/RenderDefaultSlots'
10
- import { v4 as uuid_v4 } from 'uuid'
11
- import { valued } from '@/utils/is'
12
- import RenderItemSlots from '@/components/RenderItemSlots'
13
- import { cleanCol, defaultItemResponsive, defaultLabelCol } from '@/utils/core'
14
- import Icon from '@/renders/Icon'
15
- import { $confirm } from '@/hooks/useMessage'
16
- import {
17
- Table as ATable,
18
- Button as AButton,
19
- Form as AForm,
20
- FormItem as AFormItem,
21
- Row as ARow,
22
- Col as ACol,
23
- Spin as ASpin,
24
- } from 'ant-design-vue'
25
- import { TablePaginationConfig } from 'ant-design-vue/es/table/interface'
2
+ import { ColumnProps, PFormItemProps, PGridProps, ResponsePathConfig } from '#/antProxy';
3
+ import { computed, useAttrs, ref, Ref, reactive, onMounted, watch, toRefs } from 'vue';
4
+ import { debounce, get, isArray, isFunction, isString, merge, omit, toNumber } from 'lodash-es';
5
+ import { eachTree } from '@/utils/treeHelper';
6
+ import { message as $message } from 'ant-design-vue';
7
+ import RenderAntItem from '@/components/RenderAntItem';
8
+ import RenderTitleSlots from '@/components/RenderTitleSlots';
9
+ import RenderDefaultSlots from '@/components/RenderDefaultSlots';
10
+ import { v4 as uuid_v4 } from 'uuid';
11
+ import { valued } from '@/utils/is';
12
+ import RenderItemSlots from '@/components/RenderItemSlots';
13
+ import { cleanCol, defaultItemResponsive, defaultLabelCol } from '@/utils/core';
14
+ import Icon from '@/renders/Icon';
15
+ import { $confirm } from '@/hooks/useMessage';
16
+ import {
17
+ Table as ATable,
18
+ Button as AButton,
19
+ Form as AForm,
20
+ FormItem as AFormItem,
21
+ Row as ARow,
22
+ Col as ACol,
23
+ Spin as ASpin,
24
+ Tooltip as ATooltip,
25
+ } from 'ant-design-vue';
26
+ import { TablePaginationConfig } from 'ant-design-vue/es/table/interface';
27
+ import { InfoCircleOutlined } from '@ant-design/icons-vue';
26
28
 
27
- const props = defineProps<PGridProps<D, F>>()
28
- const {
29
- formConfig,
30
- pageConfig,
31
- columns,
32
- toolbarConfig,
33
- proxyConfig,
34
- tableConfig,
35
- selectConfig,
36
- scrollMode,
37
- } = toRefs(props)
38
- const loading = reactive({
39
- table: false,
40
- form: false,
41
- })
42
- const submitOnReset = true
43
- const boxEl = ref<HTMLDivElement>()
44
- const renderHeight = ref(500)
45
- const selectedRowKeys = ref<string[] | number[]>([])
46
- const innerToolbarHandler = (code: string) => {
47
- const { ajax } = proxyConfig.value!
48
- switch (code) {
49
- case 'multiDelete':
50
- if (ajax.multiDelete) {
51
- if (selectedRowKeys.value.length > 0) {
52
- $confirm({
53
- title: '警告',
54
- content: '确认删除选中的数据吗?',
55
- }).then(() => {
56
- loading.table = true
57
- ajax.multiDelete!(selectedRowKeys.value)
29
+ const props = defineProps<PGridProps<D, F>>();
30
+ const {
31
+ formConfig,
32
+ pageConfig,
33
+ columns,
34
+ toolbarConfig,
35
+ proxyConfig,
36
+ tableConfig,
37
+ selectConfig,
38
+ scrollMode,
39
+ } = toRefs(props);
40
+ const loading = reactive({
41
+ table: false,
42
+ form: false,
43
+ });
44
+ const submitOnReset = true;
45
+ const boxEl = ref<HTMLDivElement>();
46
+ const renderHeight = ref(500);
47
+ const selectedRowKeys = ref<string[] | number[]>([]);
48
+ const innerToolbarHandler = (code: string) => {
49
+ const { ajax } = proxyConfig.value!;
50
+ switch (code) {
51
+ case 'multiDelete':
52
+ if (ajax.multiDelete) {
53
+ if (selectedRowKeys.value.length > 0) {
54
+ $confirm({
55
+ title: '警告',
56
+ content: '确认删除选中的数据吗?',
57
+ }).then(() => {
58
+ loading.table = true;
59
+ ajax.multiDelete!(selectedRowKeys.value)
58
60
  .then(() => {
59
- $message.success('删除成功')
60
- resetPage()
61
+ $message.success('删除成功');
62
+ resetPage();
61
63
  })
62
64
  .catch(() => {
63
- $message.error('删除失败')
65
+ $message.error('删除失败');
64
66
  })
65
67
  .finally(() => {
66
- loading.table = false
67
- })
68
- })
69
- } else {
70
- $message.warn('请选择要删除的数据')
68
+ loading.table = false;
69
+ });
70
+ });
71
+ } else {
72
+ $message.warn('请选择要删除的数据');
73
+ }
71
74
  }
72
- }
73
- break
74
- }
75
- }
76
- const slotTitleColumns = computed(() => {
77
- const cols: ColumnProps<D>[] = []
78
- eachTree(columns.value, (col) => {
79
- if (col.slots && col.slots.title) {
80
- if (!col.field) {
81
- col.field = '__holder__' + cols.length
82
- }
83
- cols.push(col)
75
+ break;
84
76
  }
85
- })
86
- return cols
87
- })
88
- const formEl = ref()
89
- const tableEl = ref()
90
- const renderFormKey = ref(uuid_v4())
91
- const renderTableKey = ref(uuid_v4())
92
- const refreshForm = () => {
93
- renderFormKey.value = uuid_v4()
94
- }
95
- const refreshTable = () => {
96
- renderTableKey.value = uuid_v4()
97
- }
98
- const debounceRefreshForm = debounce(refreshForm, 100)
99
- const debounceRefreshTable = debounce(refreshTable, 100)
100
- const slotDefaultColumns = computed(() => {
101
- const cols: ColumnProps<D>[] = []
102
- eachTree(columns.value, (col) => {
103
- if ((col.slots && col.slots.default) || col.formatter || col.cellRender) {
104
- if (!col.field) {
105
- col.field = '__holder__' + cols.length
77
+ };
78
+ const slotTitleColumns = computed(() => {
79
+ const cols: ColumnProps<D>[] = [];
80
+ eachTree(columns.value, (col) => {
81
+ if (col.slots && col.slots.title) {
82
+ if (!col.field) {
83
+ col.field = '__holder__' + cols.length;
84
+ }
85
+ cols.push(col);
106
86
  }
107
- cols.push(col)
108
- }
109
- })
110
- return cols
111
- })
112
- const pagination = reactive<IPage>({
113
- page: 1,
114
- size: pageConfig.value?.pageSize ?? 10,
115
- })
116
- const dataSeed = ref(0)
117
- const totalCount = ref(0)
118
- const tableData = ref<D[]>([]) as Ref<D[]>
119
- const mode = computed<'list' | 'pagination' | 'bad'>(() =>
87
+ });
88
+ return cols;
89
+ });
90
+ const formEl = ref();
91
+ const tableEl = ref();
92
+ const renderFormKey = ref(uuid_v4());
93
+ const renderTableKey = ref(uuid_v4());
94
+ const refreshForm = () => {
95
+ renderFormKey.value = uuid_v4();
96
+ };
97
+ const refreshTable = () => {
98
+ renderTableKey.value = uuid_v4();
99
+ };
100
+ const debounceRefreshForm = debounce(refreshForm, 100);
101
+ const debounceRefreshTable = debounce(refreshTable, 100);
102
+ const slotDefaultColumns = computed(() => {
103
+ const cols: ColumnProps<D>[] = [];
104
+ eachTree(columns.value, (col) => {
105
+ if ((col.slots && col.slots.default) || col.formatter || col.cellRender) {
106
+ if (!col.field) {
107
+ col.field = '__holder__' + cols.length;
108
+ }
109
+ cols.push(col);
110
+ }
111
+ });
112
+ return cols;
113
+ });
114
+ const pagination = reactive<IPage>({
115
+ page: 1,
116
+ size: pageConfig.value?.pageSize ?? 10,
117
+ });
118
+ const dataSeed = ref(0);
119
+ const totalCount = ref(0);
120
+ const tableData = ref<D[]>([]) as Ref<D[]>;
121
+ const mode = computed<'list' | 'pagination' | 'bad'>(() =>
120
122
  proxyConfig.value && proxyConfig.value.ajax
121
- ? pageConfig.value
122
- ? 'pagination'
123
- : 'list'
124
- : 'bad',
125
- )
126
- const attrs = useAttrs()
127
- const emit = defineEmits([
128
- 'query',
129
- 'reset',
130
- 'update:tableData',
131
- 'toolbarButtonClick',
132
- 'toolbarToolClick',
133
- 'pick',
134
- ])
135
- const toolBtnClick = (code: string) => {
136
- emit('toolbarButtonClick', {
137
- data: tableData.value,
138
- code,
139
- selectedKeys: selectedRowKeys.value,
140
- })
141
- innerToolbarHandler(code)
142
- }
143
- const toolToolClick = (code: string) => {
144
- emit('toolbarToolClick', { data: tableData.value, code, selectedKeys: selectedRowKeys.value })
145
- innerToolbarHandler(code)
146
- }
147
- const queryFormData = ref<Partial<F>>({}) as Ref<Partial<F>>
148
- const pickRow = ({ row, field }: { row: D; field: string }) => {
149
- emit('pick', { row, field })
150
- }
151
- const resetQueryFormData = (lazy?: boolean) => {
152
- if (formConfig.value && formConfig.value.items.length > 0) {
153
- if (formConfig.value.customReset) {
154
- formConfig.value.customReset()
155
- } else {
156
- const obj: Partial<F> = {}
157
- eachTree(formConfig.value.items, (item) => {
158
- if (item.field && item.itemRender) {
159
- if (valued(item.itemRender.defaultValue)) {
160
- obj[item.field] = item.itemRender.defaultValue
161
- } else {
162
- obj[item.field] = undefined
123
+ ? pageConfig.value
124
+ ? 'pagination'
125
+ : 'list'
126
+ : 'bad',
127
+ );
128
+ const attrs = useAttrs();
129
+ const emit = defineEmits([
130
+ 'query',
131
+ 'reset',
132
+ 'update:tableData',
133
+ 'toolbarButtonClick',
134
+ 'toolbarToolClick',
135
+ 'pick',
136
+ ]);
137
+ const toolBtnClick = (code: string) => {
138
+ emit('toolbarButtonClick', {
139
+ data: tableData.value,
140
+ code,
141
+ selectedKeys: selectedRowKeys.value,
142
+ });
143
+ innerToolbarHandler(code);
144
+ };
145
+ const toolToolClick = (code: string) => {
146
+ emit('toolbarToolClick', { data: tableData.value, code, selectedKeys: selectedRowKeys.value });
147
+ innerToolbarHandler(code);
148
+ };
149
+ const queryFormData = ref<Partial<F>>({}) as Ref<Partial<F>>;
150
+ const pickRow = ({ row, field }: { row: D; field: string }) => {
151
+ emit('pick', { row, field });
152
+ };
153
+ const resetQueryFormData = (lazy?: boolean) => {
154
+ if (formConfig.value && formConfig.value.items.length > 0) {
155
+ if (formConfig.value.customReset) {
156
+ formConfig.value.customReset();
157
+ } else {
158
+ const obj: Partial<F> = {};
159
+ eachTree(formConfig.value.items, (item) => {
160
+ if (item.field && item.itemRender) {
161
+ if (valued(item.itemRender.defaultValue)) {
162
+ obj[item.field] = item.itemRender.defaultValue;
163
+ } else {
164
+ obj[item.field] = undefined;
165
+ }
163
166
  }
164
- }
165
- })
166
- queryFormData.value = obj
167
+ });
168
+ queryFormData.value = obj;
169
+ }
170
+ refreshForm();
167
171
  }
168
- refreshForm()
169
- }
170
-
171
- pagination.page = 1
172
- if (!lazy) {
173
- debounceFetchData()
174
- }
175
- }
176
- const handleResponse = (response: Recordable, pathConfig?: ResponsePathConfig<D>) =>
172
+
173
+ pagination.page = 1;
174
+ if (!lazy) {
175
+ debounceFetchData();
176
+ }
177
+ };
178
+ const handleResponse = (response: Recordable, pathConfig?: ResponsePathConfig<D>) =>
177
179
  pathConfig
178
- ? {
180
+ ? {
179
181
  list: isString(pathConfig.list)
180
- ? get(response, pathConfig.list)
181
- : isFunction(pathConfig.list)
182
- ? pathConfig.list(response)
183
- : undefined,
182
+ ? get(response, pathConfig.list)
183
+ : isFunction(pathConfig.list)
184
+ ? pathConfig.list(response)
185
+ : undefined,
184
186
  total: isString(pathConfig.total)
185
- ? get(response, pathConfig.total)
186
- : isFunction(pathConfig.total)
187
- ? pathConfig.total(response)
188
- : undefined,
187
+ ? get(response, pathConfig.total)
188
+ : isFunction(pathConfig.total)
189
+ ? pathConfig.total(response)
190
+ : undefined,
189
191
  result: isString(pathConfig.result)
190
- ? get(response, pathConfig.result)
191
- : isFunction(pathConfig.result)
192
- ? pathConfig.result(response)
193
- : undefined,
192
+ ? get(response, pathConfig.result)
193
+ : isFunction(pathConfig.result)
194
+ ? pathConfig.result(response)
195
+ : undefined,
194
196
  message: isString(pathConfig.message)
195
- ? get(response, pathConfig.message)
196
- : isFunction(pathConfig.message)
197
- ? pathConfig.message(response)
198
- : undefined,
197
+ ? get(response, pathConfig.message)
198
+ : isFunction(pathConfig.message)
199
+ ? pathConfig.message(response)
200
+ : undefined,
199
201
  }
200
- : {
202
+ : {
201
203
  list: response,
202
- }
203
- const enoughSpacing = ref(true)
204
- const reload = () => {
205
- return resetQueryFormData()
206
- }
207
- const resetPage = () => {
208
- pagination.page = 1
209
- selectedRowKeys.value = []
210
- return fetchData()
211
- }
212
- /**
213
- * @description
214
- * @param p
215
- * @param _filters todo filters
216
- * @param _sorter todo sorter
217
- */
218
- const handleTableChange = (p: TablePaginationConfig, _filters, _sorter) => {
219
- pagination.page = p.current!
220
- pagination.size = p.pageSize!
221
- return fetchData()
222
- }
204
+ };
205
+ const enoughSpacing = ref(true);
206
+ const reload = () => {
207
+ return resetQueryFormData();
208
+ };
209
+ const resetPage = () => {
210
+ pagination.page = 1;
211
+ selectedRowKeys.value = [];
212
+ return fetchData();
213
+ };
214
+ /**
215
+ * @description
216
+ * @param p
217
+ * @param _filters todo filters
218
+ * @param _sorter todo sorter
219
+ */
220
+ const handleTableChange = (p: TablePaginationConfig, _filters, _sorter) => {
221
+ pagination.page = p.current!;
222
+ pagination.size = p.pageSize!;
223
+ return fetchData();
224
+ };
223
225
 
224
- const fetchData = () =>
226
+ const fetchData = () =>
225
227
  new Promise<D[]>((resolve) => {
226
228
  if (mode.value !== 'bad') {
227
- loading.form = true
228
- loading.table = true
229
- const { ajax } = proxyConfig.value!
229
+ loading.form = true;
230
+ loading.table = true;
231
+ const { ajax } = proxyConfig.value!;
230
232
  ajax
231
- .query({
232
- form: queryFormData.value,
233
- page: pagination,
234
- })
235
- .then((response) => {
236
- const { list, total, result, message } = handleResponse(
237
- response,
238
- proxyConfig.value!.response,
239
- )
240
- if (list) {
241
- tableData.value = list as D[]
242
- dataSeed.value++
243
- } else if (result) {
244
- tableData.value = result as D[]
245
- totalCount.value = total ?? result.length
246
- dataSeed.value++
247
- } else {
248
- tableData.value = []
249
- dataSeed.value++
250
- if (message) {
251
- $message.warn(message)
252
- }
233
+ .query({
234
+ form: queryFormData.value,
235
+ page: pagination,
236
+ })
237
+ .then((response) => {
238
+ const { list, total, result, message } = handleResponse(
239
+ response,
240
+ proxyConfig.value!.response,
241
+ );
242
+ if (list) {
243
+ tableData.value = list as D[];
244
+ dataSeed.value++;
245
+ } else if (result) {
246
+ tableData.value = result as D[];
247
+ totalCount.value = total ?? result.length;
248
+ dataSeed.value++;
249
+ } else {
250
+ tableData.value = [];
251
+ dataSeed.value++;
252
+ if (message) {
253
+ $message.warn(message);
253
254
  }
254
- resolve(tableData.value as D[])
255
- })
256
- .catch((e) => {
257
- console.error('fetchData error', e)
258
- resolve([] as D[])
259
- })
260
- .finally(() => {
261
- loading.form = false
262
- loading.table = false
263
- })
255
+ }
256
+ resolve(tableData.value as D[]);
257
+ })
258
+ .catch((e) => {
259
+ console.error('fetchData error', e);
260
+ resolve([] as D[]);
261
+ })
262
+ .finally(() => {
263
+ loading.form = false;
264
+ loading.table = false;
265
+ });
264
266
  }
265
- })
266
- const debounceFetchData = debounce(fetchData, 160)
267
- const passQuery = (params: Partial<F>) => {
268
- Object.assign(queryFormData.value, params)
269
- pagination.page = 1
270
- return debounceFetchData()
271
- }
272
- const pg = computed(() =>
267
+ });
268
+ const debounceFetchData = debounce(fetchData, 160);
269
+ const passQuery = (params: Partial<F>) => {
270
+ Object.assign(queryFormData.value, params);
271
+ pagination.page = 1;
272
+ return debounceFetchData();
273
+ };
274
+ const pg = computed(() =>
273
275
  mode.value === 'pagination'
274
- ? {
276
+ ? {
275
277
  current: pagination.page,
276
278
  total: totalCount.value,
277
279
  pageSize: pagination.size,
@@ -279,122 +281,151 @@ const pg = computed(() =>
279
281
  showSizeChanger: true,
280
282
  showTotal: (total: number) => `共${total}条数据`,
281
283
  }
282
- : false,
283
- )
284
- const defaultTableConfig = {
285
- size: 'small',
286
- sticky: true,
287
- transformCellText: ({ text }) => {
288
- return isArray(text) && text.length === 0 ? '-' : text
289
- },
290
- }
291
- const tc = computed(() =>
284
+ : false,
285
+ );
286
+ const defaultTableConfig = {
287
+ size: 'small',
288
+ sticky: true,
289
+ transformCellText: ({ text }) => {
290
+ return isArray(text) && text.length === 0 ? '-' : text;
291
+ },
292
+ };
293
+ const tc = computed(() =>
292
294
  merge(
293
- {},
294
- defaultTableConfig,
295
- tableConfig?.value ?? {},
296
- selectConfig.value
297
- ? {
298
- rowSelection: {
299
- type: selectConfig.value.multiple ? 'checkbox' : 'radio',
300
- preserveSelectedRowKeys: true,
301
- selectedRowKeys: selectedRowKeys.value,
302
- onChange: (selectedKeys: string[] | number[]) => {
303
- selectedRowKeys.value = selectedKeys
304
- },
295
+ {},
296
+ defaultTableConfig,
297
+ tableConfig?.value ?? {},
298
+ selectConfig.value
299
+ ? {
300
+ rowSelection: {
301
+ type: selectConfig.value.multiple ? 'checkbox' : 'radio',
302
+ preserveSelectedRowKeys: true,
303
+ selectedRowKeys: selectedRowKeys.value,
304
+ onChange: (selectedKeys: string[] | number[]) => {
305
+ selectedRowKeys.value = selectedKeys;
305
306
  },
306
- }
307
- : {},
307
+ },
308
+ }
309
+ : {},
308
310
  ),
309
- )
310
- /*omit({labelCol:defaultLabelCol,...formConfig},['items'])*/
311
- const fc = computed(() => omit({ labelCol: defaultLabelCol, ...formConfig.value }, ['items']))
312
- const handleFormSubmit = () => {
313
- resetPage()
314
- }
311
+ );
312
+ /*omit({labelCol:defaultLabelCol,...formConfig},['items'])*/
313
+ const fc = computed(() => omit({ labelCol: defaultLabelCol, ...formConfig.value }, ['items']));
314
+ const handleFormSubmit = () => {
315
+ resetPage();
316
+ };
315
317
 
316
- watch(
318
+ watch(
317
319
  () => formConfig.value,
318
320
  () => {
319
- debounceRefreshForm()
321
+ debounceRefreshForm();
320
322
  },
321
323
  { deep: true },
322
- )
323
- watch(
324
+ );
325
+ watch(
324
326
  () => [columns.value, proxyConfig.value, toolbarConfig.value],
325
327
  () => {
326
- debounceRefreshTable()
328
+ debounceRefreshTable();
327
329
  },
328
330
  { deep: true },
329
- )
330
- defineExpose({
331
- commitProxy: {
332
- query: debounceFetchData,
333
- reload,
334
- reloadPage: resetPage,
335
- passQuery,
336
- },
337
- $table: computed(() => tableEl.value),
338
- selectedRowKeys: computed(() => selectedRowKeys.value),
339
- $form: computed(() => formEl.value),
340
- })
341
- onMounted(() => {
342
- /*判断本组件所在容器DOM*/
343
- const pNode = boxEl.value?.parentElement
344
- const ph = pNode ? window.getComputedStyle(pNode).height : '0px'
345
- renderHeight.value = props.renderY ?? toNumber(ph.replace('px', '')) - (props.fitHeight ?? 170) - (!!props.toolbarConfig ? 30 : 0) - (Math.ceil((props.formConfig?.items?.length ?? 0) / 4) * 35)
346
- enoughSpacing.value = toNumber(ph.replace('px', '')) > 600
347
- resetQueryFormData(props.manualFetch)
348
- })
331
+ );
332
+ defineExpose({
333
+ commitProxy: {
334
+ query: debounceFetchData,
335
+ reload,
336
+ reloadPage: resetPage,
337
+ passQuery,
338
+ },
339
+ $table: computed(() => tableEl.value),
340
+ selectedRowKeys: computed(() => selectedRowKeys.value),
341
+ $form: computed(() => formEl.value),
342
+ });
343
+ onMounted(() => {
344
+ /*判断本组件所在容器DOM*/
345
+ const pNode = boxEl.value?.parentElement;
346
+ const ph = pNode ? window.getComputedStyle(pNode).height : '0px';
347
+ renderHeight.value =
348
+ props.renderY ??
349
+ toNumber(ph.replace('px', '')) -
350
+ (props.fitHeight ?? 170) -
351
+ (!!props.toolbarConfig ? 30 : 0) -
352
+ Math.ceil((props.formConfig?.items?.length ?? 0) / 4) * 35;
353
+ enoughSpacing.value = toNumber(ph.replace('px', '')) > 600;
354
+ resetQueryFormData(props.manualFetch);
355
+ });
349
356
  </script>
350
357
  <template>
351
358
  <div ref="boxEl" class="h-full p-wrapper flex flex-col gap-8px overflow-y-auto" v-bind="attrs">
352
359
  <div v-if="mode === 'bad'">请检查配置</div>
353
360
  <template v-else>
354
361
  <div
355
- v-if="formConfig?.items?.some((s: PFormItemProps<F>) => s.field && s.itemRender)"
356
- class="p-pane p-form-wrapper"
362
+ v-if="formConfig?.items?.some((s: PFormItemProps<F>) => s.field && s.itemRender)"
363
+ class="p-pane p-form-wrapper"
357
364
  >
358
365
  <a-spin :spinning="loading.form">
359
366
  <a-form
360
- :key="renderFormKey"
361
- ref="formEl"
362
- :model="queryFormData"
363
- v-bind="fc"
364
- @submit="handleFormSubmit"
367
+ :key="renderFormKey"
368
+ ref="formEl"
369
+ :model="queryFormData"
370
+ v-bind="fc"
371
+ @submit="handleFormSubmit"
365
372
  >
366
373
  <a-row :gutter="[6, 12]">
367
374
  <a-col
368
- v-for="(item, idx) in formConfig!.items"
369
- :key="'_col_' + idx"
370
- v-bind="item.col ?? (item.span ? { span: item.span } : defaultItemResponsive)"
375
+ v-for="(item, idx) in formConfig!.items"
376
+ :key="'_col_' + idx"
377
+ v-bind="item.col ?? (item.span ? { span: item.span } : defaultItemResponsive)"
371
378
  >
372
379
  <a-form-item
373
- :key="'_item_' + idx"
374
- :class="`p-content-align-${item.align ?? 'left'}`"
375
- :label="item.title"
376
- :name="item.field"
377
- v-bind="omit(item, ['field', 'title', 'span', 'col', 'itemRender'])"
380
+ :key="'_item_' + idx"
381
+ :class="`p-content-align-${item.align ?? 'left'} ${item.forceRequired ? 'p-required' : ''}`"
382
+ :label="item.title"
383
+ :name="item.field"
384
+ v-bind="
385
+ omit(item, [
386
+ 'field',
387
+ 'title',
388
+ 'span',
389
+ 'col',
390
+ 'itemRender',
391
+ 'forceRequired',
392
+ 'tooltip',
393
+ ])
394
+ "
378
395
  >
379
396
  <render-item-slots
380
- v-if="item.slots?.default"
381
- :key="'_sl_'+(item.field??'_')+'_'+idx"
382
- :form-data="queryFormData"
383
- :item="item"
384
- :pass-trigger="() => {}"
397
+ v-if="item.slots?.default"
398
+ :key="'_sl_' + (item.field ?? '_') + '_' + idx"
399
+ :form-data="queryFormData"
400
+ :item="item"
401
+ :pass-trigger="() => {}"
385
402
  />
386
403
  <render-ant-item
387
- v-else-if="item.itemRender?.name"
388
- :key="'_re_'+(item.field??'_')+'_'+idx"
389
- :default-handler="{
404
+ v-else-if="item.itemRender?.name"
405
+ :key="'_re_' + (item.field ?? '_') + '_' + idx"
406
+ :default-handler="{
390
407
  reset: () => {
391
408
  resetQueryFormData(!submitOnReset);
392
409
  },
393
410
  }"
394
- :item-render="item.itemRender"
395
- :render-form-params="{ data: queryFormData, field: item.field }"
411
+ :item-render="item.itemRender"
412
+ :render-form-params="{ data: queryFormData, field: item.field }"
396
413
  />
397
414
  <span v-else></span>
415
+ <template #tooltip v-if="item.tooltipConfig">
416
+ <a-tooltip
417
+ v-if="isFunction(item.tooltipConfig.title)"
418
+ v-bind="omit(item.tooltipConfig, ['title'])"
419
+ >
420
+ <InfoCircleOutlined class="cursor-pointer py-4x px-2x" />
421
+ <template #title>
422
+ <div v-html="item.tooltipConfig.title()"></div>
423
+ </template>
424
+ </a-tooltip>
425
+ <a-tooltip v-else v-bind="item.tooltipConfig">
426
+ <InfoCircleOutlined class="cursor-pointer py-4x px-2x" />
427
+ </a-tooltip>
428
+ </template>
398
429
  </a-form-item>
399
430
  </a-col>
400
431
  </a-row>
@@ -402,19 +433,19 @@ onMounted(() => {
402
433
  </a-spin>
403
434
  </div>
404
435
  <div
405
- v-if="toolbarConfig"
406
- class="p-toolbar-wrapper flex items-center w-full justify-between p-theme-bg pt-8px px-16px"
436
+ v-if="toolbarConfig"
437
+ class="p-toolbar-wrapper flex items-center w-full justify-between p-theme-bg pt-8px px-16px"
407
438
  >
408
439
  <div class="flex items-center flex-1 gap-4px">
409
440
  <template v-if="toolbarConfig.buttons && toolbarConfig.buttons.length > 0">
410
441
  <a-button
411
- v-for="(btn, idx) in toolbarConfig.buttons"
412
- :key="idx"
413
- :type="btn.type"
414
- size="small"
415
- @click="toolBtnClick(btn.code)"
442
+ v-for="(btn, idx) in toolbarConfig.buttons"
443
+ :key="idx"
444
+ :type="btn.type"
445
+ size="small"
446
+ @click="toolBtnClick(btn.code)"
416
447
  >
417
- <Icon v-if="btn.icon" :icon="btn.icon"/>
448
+ <Icon v-if="btn.icon" :icon="btn.icon" />
418
449
  {{ btn.content }}
419
450
  </a-button>
420
451
  </template>
@@ -422,49 +453,49 @@ onMounted(() => {
422
453
  <span class="flex items-center gap-4px">
423
454
  <template v-if="toolbarConfig.tools && toolbarConfig.tools.length > 0">
424
455
  <a-button
425
- v-for="(tool, idx) in toolbarConfig.tools"
426
- :key="idx"
427
- :type="tool.type"
428
- size="small"
429
- @click="toolToolClick(tool.code)"
456
+ v-for="(tool, idx) in toolbarConfig.tools"
457
+ :key="idx"
458
+ :type="tool.type"
459
+ size="small"
460
+ @click="toolToolClick(tool.code)"
430
461
  >
431
- <Icon :icon="tool.icon"/>
462
+ <Icon :icon="tool.icon" />
432
463
  </a-button>
433
464
  </template>
434
465
  </span>
435
466
  </div>
436
467
  <div :class="`p-pane flex-1 ${enoughSpacing ? 'h-0' : ''} p-${scrollMode ?? 'inner'}-scroll`">
437
468
  <a-table
438
- :key="renderTableKey + '_table'"
439
- :row-key="rowKey ?? 'id'"
440
- ref="tableEl"
441
- :columns="columns.map((c) => cleanCol(c as Recordable))"
442
- :data-source="tableData"
443
- :loading="loading.table"
444
- :pagination="pg"
445
- v-bind="tc"
446
- :scroll="{
469
+ :key="renderTableKey + '_table'"
470
+ :row-key="rowKey ?? 'id'"
471
+ ref="tableEl"
472
+ :columns="columns.map((c) => cleanCol(c as Recordable))"
473
+ :data-source="tableData"
474
+ :loading="loading.table"
475
+ :pagination="pg"
476
+ v-bind="tc"
477
+ :scroll="{
447
478
  x: 'max-content',
448
479
  y: renderHeight,
449
480
  }"
450
- @change="handleTableChange"
481
+ @change="handleTableChange"
451
482
  >
452
483
  <template v-if="slotTitleColumns.length > 0" #headerCell="{ column }">
453
484
  <render-title-slots
454
- v-if="slotTitleColumns.some((s) => column.key && s.field === column.key)"
455
- :key="renderTableKey + '_title_' + dataSeed + '_slot_' + column.key"
456
- :column="slotTitleColumns.find((f) => column.key && f.field === column.key)!"
485
+ v-if="slotTitleColumns.some((s) => column.key && s.field === column.key)"
486
+ :key="renderTableKey + '_title_' + dataSeed + '_slot_' + column.key"
487
+ :column="slotTitleColumns.find((f) => column.key && f.field === column.key)!"
457
488
  />
458
489
  </template>
459
490
  <template v-if="slotDefaultColumns.length > 0" #bodyCell="{ column, record, index }">
460
491
  <render-default-slots
461
- v-if="slotDefaultColumns.some((s) => column.key && s.field === column.key)"
462
- :key="renderTableKey + '_cell_' + dataSeed + '_slot_' + column.key"
463
- :column="slotDefaultColumns.find((f) => column.key && f.field === column.key)!"
464
- :default-handler="{ pick: pickRow }"
465
- :row="record"
466
- :row-index="index"
467
- :table-data="tableData as Recordable[]"
492
+ v-if="slotDefaultColumns.some((s) => column.key && s.field === column.key)"
493
+ :key="renderTableKey + '_cell_' + dataSeed + '_slot_' + column.key"
494
+ :column="slotDefaultColumns.find((f) => column.key && f.field === column.key)!"
495
+ :default-handler="{ pick: pickRow }"
496
+ :row="record"
497
+ :row-index="index"
498
+ :table-data="tableData as Recordable[]"
468
499
  />
469
500
  </template>
470
501
  </a-table>