diff --git a/config/unplugin/auto-import.ts b/config/unplugin/auto-import.ts index 69e7b9a..6d2de4c 100644 --- a/config/unplugin/auto-import.ts +++ b/config/unplugin/auto-import.ts @@ -21,7 +21,7 @@ export function configAutoImport() { '@vueuse/core', { dayjs: [['default', 'dayjs']], - 'lodash-es': ['cloneDeep', 'omit', 'pick', 'union', 'uniq', 'isNumber', 'uniqBy', 'isEmpty'], + 'lodash-es': ['cloneDeep', 'omit', 'pick', 'union', 'uniq', 'isNumber', 'uniqBy', 'isEmpty', 'merge'], '@/hooks': ['useModal'], }, ], diff --git a/src/hooks/useTableSelectionWithPagination.ts b/src/hooks/useTableSelectionWithPagination.ts new file mode 100644 index 0000000..2fd6c4b --- /dev/null +++ b/src/hooks/useTableSelectionWithPagination.ts @@ -0,0 +1,87 @@ +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; +} + +const DEFAULT_PAGE_INFO = { + page: 1, + pageSize: 20, + total: 0, +}; + +export function useTableSelectionWithPagination(options: UseTableSelectionWithPaginationOptions = {}) { + const rowKey = options.rowKey || 'id'; + + const selectedRowKeys = ref>([]); + const selectedRows = ref([]); + + const pageInfo = ref(merge({}, DEFAULT_PAGE_INFO, options.pageInfo)); + + const dataSource = ref([]); + + // 单行选择 + 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]); + } + }; + + // 全选/取消全选 + const handleSelectAll = (checked: boolean) => { + 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])); + } + }; + + 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); + }; + + const rowSelection = computed(() => ({ + type: 'checkbox', + showCheckedAll: true, + })); + + return { + selectedRowKeys, + selectedRows, + dataSource, + pageInfo, + onPageChange, + onPageSizeChange, + rowSelection, + handleSelect, + handleSelectAll, + }; +} diff --git a/src/views/property-marketing/put-account/account-manage/components/select-sub-account-modal/index.vue b/src/views/property-marketing/put-account/account-manage/components/select-sub-account-modal/index.vue index 126350a..032f9d4 100644 --- a/src/views/property-marketing/put-account/account-manage/components/select-sub-account-modal/index.vue +++ b/src/views/property-marketing/put-account/account-manage/components/select-sub-account-modal/index.vue @@ -44,16 +44,12 @@ ref="tableRef" :data="dataSource" column-resizable - :row-selection="{ - type: 'checkbox', - showCheckedAll: true, - width: 48, - }" - row-key="account_id" - :selected-keys="selectedRowKeys" + :row-selection="rowSelection" + :row-key="ROW_KEY" :pagination="false" :scroll="{ x: '100%', y: '100%' }" class="w-100% flex-1 overflow-hidden" + :selected-keys="selectedRowKeys" bordered @select="handleSelect" @select-all="handleSelectAll" @@ -97,7 +93,7 @@ show-jumper show-page-size :current="pageInfo.page" - :page-size="pageInfo.pageSize" + :page-size="pageInfo.page_size" @change="onPageChange" @page-size-change="onPageSizeChange" /> @@ -126,6 +122,7 @@ import { INITIAL_FORM, INITIAL_PAGE_INFO, TABLE_COLUMNS } from './constants'; import { formatTableField } from '@/utils/tools'; import { postSubAccount, postAddSubAccount } from '@/api/all/propertyMarketing'; +import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination'; const emits = defineEmits('confirm'); const update = inject('update'); @@ -133,13 +130,29 @@ const closeAddAccountModal = inject('closeAddAccountModal'); const closeAuthorizeAccountModal = inject('closeAuthorizeAccountModal'); const visible = ref(false); -const dataSource = ref([]); const query = ref(cloneDeep(INITIAL_FORM)); -const pageInfo = ref(cloneDeep(INITIAL_PAGE_INFO)); const form = ref(null); -const selectedAccounts = ref([]); -const selectedRowKeys = ref([]); +const ROW_KEY = 'account_id'; +const { + selectedRowKeys, + selectedRows: selectedAccounts, + dataSource, + pageInfo, + onPageChange, + onPageSizeChange, + rowSelection, + handleSelect, + handleSelectAll, +} = useTableSelectionWithPagination({ + rowKey: ROW_KEY, + onPageChange: () => { + getData(); + }, + onPageSizeChange: () => { + getData(); + }, +}); const open = (formData) => { const { platform, account, password } = formData; @@ -152,16 +165,15 @@ const open = (formData) => { }; getData(); - visible.value = true; }; + const onClose = () => { form.value = null; selectedAccounts.value = []; selectedRowKeys.value = []; query.value = cloneDeep(INITIAL_FORM); pageInfo.value = cloneDeep(INITIAL_PAGE_INFO); - visible.value = false; }; @@ -181,12 +193,6 @@ const getData = async () => { ...query.value, page, page_size, - // platform: 0, - // account: '543366265@qq.com', - // password: 'Xiaoti2025@', - // // page: 1, - // // page_size: 10, - // account_id: '', }); if (code === 200) { dataSource.value = data?.data ?? []; @@ -199,43 +205,6 @@ const reload = () => { getData(); }; -const handleSelect = (selectedKeys, rowKey, record) => { - const select = selectedKeys.includes(rowKey); - selectedRowKeys.value = selectedKeys; - - if (select) { - selectedAccounts.value.push(record); - } else { - selectedAccounts.value = selectedAccounts.value.filter((v) => v.account_id !== record.account_id); - } -}; - -const handleSelectAll = (checked) => { - const currentPageAccounts = dataSource.value; - const currentPageKeys = currentPageAccounts.map((v) => v.account_id); - - if (checked) { - selectedRowKeys.value = Array.from(new Set([...selectedRowKeys.value, ...currentPageKeys])); - - const allAccounts = [...selectedAccounts.value, ...currentPageAccounts]; - const map = new Map(); - allAccounts.forEach((acc) => map.set(acc.account_id, acc)); - selectedAccounts.value = Array.from(map.values()); - } else { - selectedRowKeys.value = selectedRowKeys.value.filter((key) => !currentPageKeys.includes(key)); - selectedAccounts.value = selectedAccounts.value.filter((acc) => !currentPageKeys.includes(acc.account_id)); - } -}; - -const onPageChange = (current) => { - pageInfo.value.page = current; - getData(); -}; -const onPageSizeChange = (pageSize) => { - pageInfo.value.page_size = pageSize; - reload(); -}; - defineExpose({ open });