2025-07-15 17:45:16 +08:00
|
|
|
import { ref, computed } from 'vue';
|
|
|
|
|
|
|
|
|
|
interface UseTableSelectionWithPaginationOptions {
|
|
|
|
|
rowKey?: string; // 主键字段名,默认 'id'
|
|
|
|
|
pageInfo?: {
|
|
|
|
|
page?: number;
|
|
|
|
|
page_size?: number;
|
|
|
|
|
total?: number;
|
|
|
|
|
};
|
|
|
|
|
onPageChange?: (page: number) => void;
|
|
|
|
|
onPageSizeChange?: (size: number) => void;
|
2025-07-22 16:29:16 +08:00
|
|
|
onSelectChange?: () => void;
|
2025-07-15 17:45:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const DEFAULT_PAGE_INFO = {
|
|
|
|
|
page: 1,
|
2025-07-15 17:46:09 +08:00
|
|
|
page_size: 20,
|
2025-07-15 17:45:16 +08:00
|
|
|
total: 0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function useTableSelectionWithPagination(options: UseTableSelectionWithPaginationOptions = {}) {
|
|
|
|
|
const rowKey = options.rowKey || 'id';
|
|
|
|
|
|
|
|
|
|
const selectedRowKeys = ref<Array<string | number>>([]);
|
|
|
|
|
const selectedRows = ref<any[]>([]);
|
|
|
|
|
|
|
|
|
|
const pageInfo = ref(merge({}, DEFAULT_PAGE_INFO, options.pageInfo));
|
|
|
|
|
|
|
|
|
|
const dataSource = ref<any[]>([]);
|
|
|
|
|
|
|
|
|
|
// 单行选择
|
|
|
|
|
const handleSelect = (selectedKeys: (string | number)[], rowKeyValue: string | number, record: any) => {
|
|
|
|
|
const select = selectedKeys.includes(rowKeyValue);
|
|
|
|
|
selectedRowKeys.value = selectedKeys;
|
|
|
|
|
|
|
|
|
|
if (select) {
|
|
|
|
|
if (!selectedRows.value.some((v) => v[rowKey] === record[rowKey])) {
|
|
|
|
|
selectedRows.value.push(record);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
selectedRows.value = selectedRows.value.filter((v) => v[rowKey] !== record[rowKey]);
|
|
|
|
|
}
|
2025-07-22 16:29:16 +08:00
|
|
|
options.onSelectChange?.();
|
2025-07-15 17:45:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 全选/取消全选
|
|
|
|
|
const handleSelectAll = (checked: boolean) => {
|
2025-08-04 17:05:44 +08:00
|
|
|
console.log('handleSelectAll', checked)
|
2025-07-15 17:45:16 +08:00
|
|
|
const currentPageRows = dataSource.value;
|
|
|
|
|
const currentPageKeys = currentPageRows.map((v) => v[rowKey]);
|
|
|
|
|
|
|
|
|
|
if (checked) {
|
|
|
|
|
selectedRowKeys.value = Array.from(new Set([...selectedRowKeys.value, ...currentPageKeys]));
|
|
|
|
|
const allRows = [...selectedRows.value, ...currentPageRows];
|
|
|
|
|
const map = new Map();
|
|
|
|
|
allRows.forEach((row) => map.set(row[rowKey], row));
|
|
|
|
|
selectedRows.value = Array.from(map.values());
|
|
|
|
|
} else {
|
|
|
|
|
selectedRowKeys.value = selectedRowKeys.value.filter((key) => !currentPageKeys.includes(key));
|
|
|
|
|
selectedRows.value = selectedRows.value.filter((row) => !currentPageKeys.includes(row[rowKey]));
|
|
|
|
|
}
|
2025-07-22 16:29:16 +08:00
|
|
|
options.onSelectChange?.();
|
2025-07-15 17:45:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onPageChange = (page: number) => {
|
|
|
|
|
pageInfo.value.page = page;
|
|
|
|
|
options.onPageChange?.(page);
|
|
|
|
|
};
|
|
|
|
|
const onPageSizeChange = (size: number) => {
|
|
|
|
|
pageInfo.value.page_size = size;
|
|
|
|
|
pageInfo.value.page = 1;
|
|
|
|
|
options.onPageSizeChange?.(size);
|
|
|
|
|
};
|
2025-07-21 12:01:32 +08:00
|
|
|
const resetPageInfo = () => {
|
|
|
|
|
pageInfo.value = cloneDeep(DEFAULT_PAGE_INFO)
|
|
|
|
|
}
|
2025-07-15 17:45:16 +08:00
|
|
|
|
|
|
|
|
const rowSelection = computed(() => ({
|
|
|
|
|
type: 'checkbox',
|
|
|
|
|
showCheckedAll: true,
|
2025-07-17 11:18:36 +08:00
|
|
|
width: 48,
|
2025-07-15 17:45:16 +08:00
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
selectedRowKeys,
|
|
|
|
|
selectedRows,
|
|
|
|
|
dataSource,
|
|
|
|
|
pageInfo,
|
|
|
|
|
onPageChange,
|
|
|
|
|
onPageSizeChange,
|
|
|
|
|
rowSelection,
|
|
|
|
|
handleSelect,
|
|
|
|
|
handleSelectAll,
|
2025-07-23 15:22:46 +08:00
|
|
|
resetPageInfo,
|
2025-07-17 15:28:20 +08:00
|
|
|
DEFAULT_PAGE_INFO,
|
2025-07-15 17:45:16 +08:00
|
|
|
};
|
|
|
|
|
}
|