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