提交 | 用户 | age
|
9c2f3f
|
1 |
import type { BasicColumn, BasicTableProps, CellFormat, GetColumnsParams } from '../types/table'; |
V |
2 |
import type { PaginationProps } from '../types/pagination'; |
391da9
|
3 |
import type { ComputedRef } from 'vue'; |
4a4321
|
4 |
import { computed, Ref, ref, reactive, toRaw, unref, watch } from 'vue'; |
9c2f3f
|
5 |
import { renderEditCell } from '../components/editable'; |
5a3861
|
6 |
import { usePermission } from '/@/hooks/web/usePermission'; |
391da9
|
7 |
import { useI18n } from '/@/hooks/web/useI18n'; |
1214b7
|
8 |
import { isArray, isBoolean, isFunction, isMap, isString } from '/@/utils/is'; |
无 |
9 |
import { cloneDeep, isEqual } from 'lodash-es'; |
391da9
|
10 |
import { formatToDate } from '/@/utils/dateUtil'; |
1214b7
|
11 |
import { ACTION_COLUMN_FLAG, DEFAULT_ALIGN, INDEX_COLUMN_FLAG, PAGE_SIZE } from '../const'; |
354904
|
12 |
|
V |
13 |
function handleItem(item: BasicColumn, ellipsis: boolean) { |
|
14 |
const { key, dataIndex, children } = item; |
|
15 |
item.align = item.align || DEFAULT_ALIGN; |
|
16 |
if (ellipsis) { |
|
17 |
if (!key) { |
d3fd22
|
18 |
item.key = typeof dataIndex == 'object' ? dataIndex.join('-') : dataIndex; |
354904
|
19 |
} |
V |
20 |
if (!isBoolean(item.ellipsis)) { |
|
21 |
Object.assign(item, { |
|
22 |
ellipsis, |
|
23 |
}); |
|
24 |
} |
|
25 |
} |
|
26 |
if (children && children.length) { |
|
27 |
handleChildren(children, !!ellipsis); |
|
28 |
} |
|
29 |
} |
|
30 |
|
|
31 |
function handleChildren(children: BasicColumn[] | undefined, ellipsis: boolean) { |
|
32 |
if (!children) return; |
|
33 |
children.forEach((item) => { |
|
34 |
const { children } = item; |
|
35 |
handleItem(item, ellipsis); |
|
36 |
handleChildren(children, ellipsis); |
|
37 |
}); |
|
38 |
} |
|
39 |
|
|
40 |
function handleIndexColumn( |
|
41 |
propsRef: ComputedRef<BasicTableProps>, |
|
42 |
getPaginationRef: ComputedRef<boolean | PaginationProps>, |
56a966
|
43 |
columns: BasicColumn[], |
faf3f4
|
44 |
) { |
391da9
|
45 |
const { t } = useI18n(); |
V |
46 |
|
5c2735
|
47 |
const { showIndexColumn, indexColumnProps, isTreeTable } = unref(propsRef); |
354904
|
48 |
|
V |
49 |
let pushIndexColumns = false; |
5c2735
|
50 |
if (unref(isTreeTable)) { |
V |
51 |
return; |
|
52 |
} |
|
53 |
columns.forEach(() => { |
354904
|
54 |
const indIndex = columns.findIndex((column) => column.flag === INDEX_COLUMN_FLAG); |
5c2735
|
55 |
if (showIndexColumn) { |
354904
|
56 |
pushIndexColumns = indIndex === -1; |
5c2735
|
57 |
} else if (!showIndexColumn && indIndex !== -1) { |
354904
|
58 |
columns.splice(indIndex, 1); |
V |
59 |
} |
|
60 |
}); |
|
61 |
|
|
62 |
if (!pushIndexColumns) return; |
|
63 |
|
|
64 |
const isFixedLeft = columns.some((item) => item.fixed === 'left'); |
|
65 |
|
|
66 |
columns.unshift({ |
|
67 |
flag: INDEX_COLUMN_FLAG, |
|
68 |
width: 50, |
|
69 |
title: t('component.table.index'), |
|
70 |
align: 'center', |
|
71 |
customRender: ({ index }) => { |
|
72 |
const getPagination = unref(getPaginationRef); |
|
73 |
if (isBoolean(getPagination)) { |
|
74 |
return `${index + 1}`; |
|
75 |
} |
|
76 |
const { current = 1, pageSize = PAGE_SIZE } = getPagination; |
056fc1
|
77 |
return ((current < 1 ? 1 : current) - 1) * pageSize + index + 1; |
354904
|
78 |
}, |
V |
79 |
...(isFixedLeft |
|
80 |
? { |
|
81 |
fixed: 'left', |
|
82 |
} |
|
83 |
: {}), |
|
84 |
...indexColumnProps, |
|
85 |
}); |
|
86 |
} |
|
87 |
|
|
88 |
function handleActionColumn(propsRef: ComputedRef<BasicTableProps>, columns: BasicColumn[]) { |
|
89 |
const { actionColumn } = unref(propsRef); |
|
90 |
if (!actionColumn) return; |
|
91 |
|
|
92 |
const hasIndex = columns.findIndex((column) => column.flag === ACTION_COLUMN_FLAG); |
|
93 |
if (hasIndex === -1) { |
|
94 |
columns.push({ |
|
95 |
...columns[hasIndex], |
|
96 |
fixed: 'right', |
|
97 |
...actionColumn, |
|
98 |
flag: ACTION_COLUMN_FLAG, |
|
99 |
}); |
|
100 |
} |
|
101 |
} |
|
102 |
|
|
103 |
export function useColumns( |
|
104 |
propsRef: ComputedRef<BasicTableProps>, |
56a966
|
105 |
getPaginationRef: ComputedRef<boolean | PaginationProps>, |
354904
|
106 |
) { |
3ef508
|
107 |
const columnsRef = ref(unref(propsRef).columns) as unknown as Ref<BasicColumn[]>; |
354904
|
108 |
let cacheColumns = unref(propsRef).columns; |
faf3f4
|
109 |
|
陈 |
110 |
const getColumnsRef = computed(() => { |
43e4c2
|
111 |
const columns = cloneDeep(unref(columnsRef)); |
cdf2c5
|
112 |
|
354904
|
113 |
handleIndexColumn(propsRef, getPaginationRef, columns); |
V |
114 |
handleActionColumn(propsRef, columns); |
116a1f
|
115 |
if (!columns) { |
V |
116 |
return []; |
|
117 |
} |
e09e0a
|
118 |
const { ellipsis } = unref(propsRef); |
V |
119 |
|
43e4c2
|
120 |
columns.forEach((item) => { |
e09e0a
|
121 |
const { customRender, slots } = item; |
V |
122 |
|
|
123 |
handleItem( |
|
124 |
item, |
56a966
|
125 |
Reflect.has(item, 'ellipsis') ? !!item.ellipsis : !!ellipsis && !customRender && !slots, |
e09e0a
|
126 |
); |
V |
127 |
}); |
43e4c2
|
128 |
return columns; |
116a1f
|
129 |
}); |
V |
130 |
|
5a3861
|
131 |
function isIfShow(column: BasicColumn): boolean { |
Z |
132 |
const ifShow = column.ifShow; |
|
133 |
|
|
134 |
let isIfShow = true; |
|
135 |
|
|
136 |
if (isBoolean(ifShow)) { |
|
137 |
isIfShow = ifShow; |
|
138 |
} |
|
139 |
if (isFunction(ifShow)) { |
|
140 |
isIfShow = ifShow(column); |
|
141 |
} |
|
142 |
return isIfShow; |
|
143 |
} |
|
144 |
const { hasPermission } = usePermission(); |
|
145 |
|
9c2f3f
|
146 |
const getViewColumns = computed(() => { |
V |
147 |
const viewColumns = sortFixedColumn(unref(getColumnsRef)); |
|
148 |
|
f7a1b0
|
149 |
const mapFn = (column) => { |
C |
150 |
const { slots, customRender, format, edit, editRow, flag } = column; |
|
151 |
|
|
152 |
if (!slots || !slots?.title) { |
|
153 |
// column.slots = { title: `header-${dataIndex}`, ...(slots || {}) }; |
|
154 |
column.customTitle = column.title; |
|
155 |
Reflect.deleteProperty(column, 'title'); |
|
156 |
} |
|
157 |
const isDefaultAction = [INDEX_COLUMN_FLAG, ACTION_COLUMN_FLAG].includes(flag!); |
|
158 |
if (!customRender && format && !edit && !isDefaultAction) { |
|
159 |
column.customRender = ({ text, record, index }) => { |
|
160 |
return formatCell(text, format, record, index); |
|
161 |
}; |
|
162 |
} |
|
163 |
|
|
164 |
// edit table |
|
165 |
if ((edit || editRow) && !isDefaultAction) { |
|
166 |
column.customRender = renderEditCell(column); |
|
167 |
} |
|
168 |
return reactive(column); |
|
169 |
}; |
|
170 |
|
7a07b7
|
171 |
const columns = cloneDeep(viewColumns); |
5a3861
|
172 |
return columns |
f7a1b0
|
173 |
.filter((column) => hasPermission(column.auth) && isIfShow(column)) |
5a3861
|
174 |
.map((column) => { |
f7a1b0
|
175 |
// Support table multiple header editable |
C |
176 |
if (column.children?.length) { |
|
177 |
column.children = column.children.map(mapFn); |
5a3861
|
178 |
} |
9c2f3f
|
179 |
|
f7a1b0
|
180 |
return mapFn(column); |
5a3861
|
181 |
}); |
faf3f4
|
182 |
}); |
陈 |
183 |
|
af5551
|
184 |
watch( |
V |
185 |
() => unref(propsRef).columns, |
|
186 |
(columns) => { |
|
187 |
columnsRef.value = columns; |
|
188 |
cacheColumns = columns?.filter((item) => !item.flag) ?? []; |
56a966
|
189 |
}, |
af5551
|
190 |
); |
74d474
|
191 |
|
c96002
|
192 |
function setCacheColumnsByField(dataIndex: string | undefined, value: Partial<BasicColumn>) { |
V |
193 |
if (!dataIndex || !value) { |
|
194 |
return; |
|
195 |
} |
|
196 |
cacheColumns.forEach((item) => { |
|
197 |
if (item.dataIndex === dataIndex) { |
|
198 |
Object.assign(item, value); |
|
199 |
return; |
|
200 |
} |
|
201 |
}); |
|
202 |
} |
354904
|
203 |
/** |
V |
204 |
* set columns |
116a1f
|
205 |
* @param columnList key|column |
354904
|
206 |
*/ |
3d55b0
|
207 |
function setColumns(columnList: Partial<BasicColumn>[] | (string | string[])[]) { |
116a1f
|
208 |
const columns = cloneDeep(columnList); |
8b3a4d
|
209 |
if (!isArray(columns)) return; |
V |
210 |
|
faf3f4
|
211 |
if (columns.length <= 0) { |
陈 |
212 |
columnsRef.value = []; |
|
213 |
return; |
|
214 |
} |
|
215 |
|
|
216 |
const firstColumn = columns[0]; |
354904
|
217 |
|
116a1f
|
218 |
const cacheKeys = cacheColumns.map((item) => item.dataIndex); |
V |
219 |
|
3d55b0
|
220 |
if (!isString(firstColumn) && !isArray(firstColumn)) { |
354904
|
221 |
columnsRef.value = columns as BasicColumn[]; |
faf3f4
|
222 |
} else { |
4a4321
|
223 |
const columnKeys = (columns as (string | string[])[]).map((m) => m.toString()); |
116a1f
|
224 |
const newColumns: BasicColumn[] = []; |
V |
225 |
cacheColumns.forEach((item) => { |
3b3f6c
|
226 |
newColumns.push({ |
N |
227 |
...item, |
4a4321
|
228 |
defaultHidden: !columnKeys.includes(item.dataIndex?.toString() || (item.key as string)), |
3b3f6c
|
229 |
}); |
116a1f
|
230 |
}); |
V |
231 |
// Sort according to another array |
|
232 |
if (!isEqual(cacheKeys, columns)) { |
|
233 |
newColumns.sort((prev, next) => { |
|
234 |
return ( |
3d55b0
|
235 |
columnKeys.indexOf(prev.dataIndex?.toString() as string) - |
LC( |
236 |
columnKeys.indexOf(next.dataIndex?.toString() as string) |
116a1f
|
237 |
); |
V |
238 |
}); |
|
239 |
} |
faf3f4
|
240 |
columnsRef.value = newColumns; |
陈 |
241 |
} |
|
242 |
} |
|
243 |
|
354904
|
244 |
function getColumns(opt?: GetColumnsParams) { |
116a1f
|
245 |
const { ignoreIndex, ignoreAction, sort } = opt || {}; |
354904
|
246 |
let columns = toRaw(unref(getColumnsRef)); |
V |
247 |
if (ignoreIndex) { |
|
248 |
columns = columns.filter((item) => item.flag !== INDEX_COLUMN_FLAG); |
|
249 |
} |
|
250 |
if (ignoreAction) { |
|
251 |
columns = columns.filter((item) => item.flag !== ACTION_COLUMN_FLAG); |
|
252 |
} |
116a1f
|
253 |
|
V |
254 |
if (sort) { |
9c2f3f
|
255 |
columns = sortFixedColumn(columns); |
116a1f
|
256 |
} |
V |
257 |
|
354904
|
258 |
return columns; |
V |
259 |
} |
116a1f
|
260 |
function getCacheColumns() { |
V |
261 |
return cacheColumns; |
|
262 |
} |
b97d58
|
263 |
function setCacheColumns(columns: BasicColumn[]) { |
G |
264 |
if (!isArray(columns)) return; |
|
265 |
cacheColumns = columns.filter((item) => !item.flag); |
|
266 |
} |
1cf2a8
|
267 |
/** |
林 |
268 |
* 拖拽列宽修改列的宽度 |
|
269 |
*/ |
|
270 |
function setColumnWidth(w: number, col: BasicColumn) { |
|
271 |
col.width = w; |
|
272 |
} |
354904
|
273 |
|
c96002
|
274 |
return { |
V |
275 |
getColumnsRef, |
|
276 |
getCacheColumns, |
|
277 |
getColumns, |
|
278 |
setColumns, |
1cf2a8
|
279 |
setColumnWidth, |
c96002
|
280 |
getViewColumns, |
V |
281 |
setCacheColumnsByField, |
b97d58
|
282 |
setCacheColumns, |
c96002
|
283 |
}; |
116a1f
|
284 |
} |
V |
285 |
|
9c2f3f
|
286 |
function sortFixedColumn(columns: BasicColumn[]) { |
116a1f
|
287 |
const fixedLeftColumns: BasicColumn[] = []; |
V |
288 |
const fixedRightColumns: BasicColumn[] = []; |
|
289 |
const defColumns: BasicColumn[] = []; |
|
290 |
for (const column of columns) { |
|
291 |
if (column.fixed === 'left') { |
|
292 |
fixedLeftColumns.push(column); |
|
293 |
continue; |
|
294 |
} |
|
295 |
if (column.fixed === 'right') { |
|
296 |
fixedRightColumns.push(column); |
|
297 |
continue; |
|
298 |
} |
|
299 |
defColumns.push(column); |
|
300 |
} |
1214b7
|
301 |
return [...fixedLeftColumns, ...defColumns, ...fixedRightColumns].filter( |
56a966
|
302 |
(item) => !item.defaultHidden, |
116a1f
|
303 |
); |
faf3f4
|
304 |
} |
9c2f3f
|
305 |
|
V |
306 |
// format cell |
|
307 |
export function formatCell(text: string, format: CellFormat, record: Recordable, index: number) { |
|
308 |
if (!format) { |
|
309 |
return text; |
|
310 |
} |
|
311 |
|
|
312 |
// custom function |
|
313 |
if (isFunction(format)) { |
|
314 |
return format(text, record, index); |
|
315 |
} |
|
316 |
|
|
317 |
try { |
|
318 |
// date type |
|
319 |
const DATE_FORMAT_PREFIX = 'date|'; |
0634f2
|
320 |
if (isString(format) && format.startsWith(DATE_FORMAT_PREFIX) && text) { |
9c2f3f
|
321 |
const dateFormat = format.replace(DATE_FORMAT_PREFIX, ''); |
V |
322 |
|
|
323 |
if (!dateFormat) { |
|
324 |
return text; |
|
325 |
} |
|
326 |
return formatToDate(text, dateFormat); |
|
327 |
} |
|
328 |
|
1214b7
|
329 |
// Map |
无 |
330 |
if (isMap(format)) { |
9c2f3f
|
331 |
return format.get(text); |
V |
332 |
} |
|
333 |
} catch (error) { |
|
334 |
return text; |
|
335 |
} |
|
336 |
} |