import { reactive, ref, computed, watch, unref } from 'vue' import { typeOf } from '@/utils/common' import useFetch from '@/hooks/useFetch' import useSection from '@/hooks/useSection' import type { Ref } from 'vue' import type { ApiKeys, BaseMultiplePageQuery, MultipleResult, ExtractApiParams, ExtractApiResponse, ExtractMultipleApiResponse, } from '@/api/api' import type { PaginationProps } from 'element-plus' import type { InstanceTable, InstanceElTable } from 'global-type' type P = Parameters type ReturnTable = { tableRef: Ref elTableRef: Ref pagination: Ref> currentPage: Ref loading: Ref data: Ref : ExtractMultipleApiResponse[]> error: unknown hasSelected?: Ref onSectionChange: (rows: ExtractMultipleApiResponse[]) => void selectedList: ExtractMultipleApiResponse[] fetchTable: () => void } type OptionalPage = Partial export type ModelType = Omit, keyof BaseMultiplePageQuery> export type MultipleResponseType = ExtractMultipleApiResponse export type ResponseType = ExtractApiResponse const DEFAULT_PARAMS: BaseMultiplePageQuery = { pageNumber: 1, pageSize: 10, } const DEFAULT_PAGINATION: Partial = { layout: 'prev,pager,next', } function isPageQuery(c: any): c is OptionalPage { return typeOf(c) === 'object' } const useTable = < T extends ApiKeys, C extends Partial> = Partial>, D extends boolean | OptionalPage = true >( api: T, additional?: C, pageQuery?: D, httpConfig: P[1] = 'post', immediate = true ): ReturnTable => { const tableRef = ref() const elTableRef = computed(() => { return tableRef?.value?.tableRef }) const { hasSelected, onSectionChange, selectedList } = useSection>() const multipleType = pageQuery !== false const baseParams = reactive( Object.assign(DEFAULT_PARAMS, isPageQuery(pageQuery) ? pageQuery : {}) ) const currentPage = computed({ get() { return baseParams.pageNumber }, set(n: number) { baseParams.pageNumber = n }, }) const payload = computed(() => { return Object.assign({}, multipleType ? baseParams : {}, additional || {}) as ExtractApiParams }) const { loading, fetch, cancel, error, result } = useFetch(api, httpConfig) const fetchTable = () => { cancel() fetch(payload.value) } watch(payload, () => fetchTable(), { immediate }) const pageCount = computed(() => { return multipleType ? (result.value as MultipleResult>)?.pageCount || 1 : 1 }) const total = computed(() => { return multipleType ? (result.value as MultipleResult>)?.totalCount || 0 : (result.value as Array).length || 0 }) const data = computed(() => { return multipleType ? (result.value as MultipleResult>)?.result || [] : (unref(result) as any) }) const pagination = computed(() => { return Object.assign(DEFAULT_PAGINATION, { pageSize: baseParams.pageSize, pageCount: pageCount.value, total: total.value, }) }) return { tableRef, elTableRef, hasSelected, onSectionChange, fetchTable, selectedList, loading, data, pagination, currentPage: currentPage, error, } } export default useTable