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 total: 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' ): ReturnTable => { const tableRef = ref() const DEFAULT_PARAMS: BaseMultiplePageQuery = { pageNumber: 1, pageSize: 10, } const modelChange = ref(false) 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 fetchTable() }, }) // watch(currentPage, (val) => { // fetchTable() // }) watch( () => additional, () => { modelChange.value = true }, { deep: true } ) const payload = computed(() => { return Object.assign({}, multipleType ? baseParams : {}, additional || {}) as ExtractApiParams }) const { loading, fetch, cancel, error, result } = useFetch(api, httpConfig) const fetchTable = () => { cancel() if (modelChange.value) { baseParams.pageNumber = 1 } fetch(payload.value) modelChange.value = false } 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, total, data, pagination, currentPage: currentPage, error, } } export default useTable