useTable.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { reactive, ref, computed, watch, unref } from 'vue'
  2. import { typeOf } from '@/utils/common'
  3. import useFetch from '@/hooks/useFetch'
  4. import useSection from '@/hooks/useSection'
  5. import type { Ref } from 'vue'
  6. import type {
  7. ApiKeys,
  8. BaseMultiplePageQuery,
  9. MultipleResult,
  10. ExtractApiParams,
  11. ExtractApiResponse,
  12. ExtractMultipleApiResponse,
  13. } from '@/api/api'
  14. import type { PaginationProps } from 'element-plus'
  15. import type { InstanceTable, InstanceElTable } from 'global-type'
  16. type P = Parameters<typeof useFetch>
  17. type ReturnTable<T extends ApiKeys, D extends boolean | OptionalPage = true> = {
  18. tableRef: Ref<InstanceTable | undefined>
  19. elTableRef: Ref<InstanceElTable | undefined>
  20. pagination: Ref<Partial<PaginationProps>>
  21. currentPage: Ref<number>
  22. total: Ref<number>
  23. loading: Ref<boolean>
  24. data: Ref<D extends false ? ExtractApiResponse<T> : ExtractMultipleApiResponse<T>[]>
  25. error: unknown
  26. hasSelected?: Ref<boolean>
  27. onSectionChange: (rows: ExtractMultipleApiResponse<T>[]) => void
  28. selectedList: ExtractMultipleApiResponse<T>[]
  29. fetchTable: () => void
  30. }
  31. type OptionalPage = Partial<BaseMultiplePageQuery>
  32. export type ModelType<T extends ApiKeys> = Omit<ExtractApiParams<T>, keyof BaseMultiplePageQuery>
  33. export type MultipleResponseType<T extends ApiKeys> = ExtractMultipleApiResponse<T>
  34. export type ResponseType<T extends ApiKeys> = ExtractApiResponse<T>
  35. // const DEFAULT_PARAMS: BaseMultiplePageQuery = {
  36. // pageNumber: 1,
  37. // pageSize: 10,
  38. // }
  39. const DEFAULT_PAGINATION: Partial<PaginationProps> = {
  40. layout: 'prev,pager,next',
  41. }
  42. function isPageQuery(c: any): c is OptionalPage {
  43. return typeOf(c) === 'object'
  44. }
  45. const useTable = <
  46. T extends ApiKeys,
  47. C extends Partial<ModelType<T>> = Partial<ModelType<T>>,
  48. D extends boolean | OptionalPage = true
  49. >(
  50. api: T,
  51. additional?: C,
  52. pageQuery?: D,
  53. httpConfig: P[1] = 'post'
  54. ): ReturnTable<T, D> => {
  55. const tableRef = ref<InstanceTable>()
  56. const DEFAULT_PARAMS: BaseMultiplePageQuery = {
  57. pageNumber: 1,
  58. pageSize: 10,
  59. }
  60. const modelChange = ref(false)
  61. const elTableRef = computed(() => {
  62. return tableRef?.value?.tableRef
  63. })
  64. const { hasSelected, onSectionChange, selectedList } = useSection<ExtractMultipleApiResponse<T>>()
  65. const multipleType = pageQuery !== false
  66. const baseParams = reactive<BaseMultiplePageQuery>(
  67. Object.assign(DEFAULT_PARAMS, isPageQuery(pageQuery) ? pageQuery : {})
  68. )
  69. const currentPage = computed({
  70. get() {
  71. return baseParams.pageNumber
  72. },
  73. set(n: number) {
  74. baseParams.pageNumber = n
  75. fetchTable()
  76. },
  77. })
  78. // watch(currentPage, (val) => {
  79. // fetchTable()
  80. // })
  81. watch(
  82. () => additional,
  83. () => {
  84. modelChange.value = true
  85. },
  86. { deep: true }
  87. )
  88. const payload = computed(() => {
  89. return Object.assign({}, multipleType ? baseParams : {}, additional || {}) as ExtractApiParams<T>
  90. })
  91. const { loading, fetch, cancel, error, result } = useFetch(api, httpConfig)
  92. const fetchTable = () => {
  93. cancel()
  94. if (modelChange.value) {
  95. baseParams.pageNumber = 1
  96. }
  97. fetch(payload.value)
  98. modelChange.value = false
  99. }
  100. const pageCount = computed(() => {
  101. return multipleType ? (result.value as MultipleResult<ExtractApiResponse<T>>)?.pageCount || 1 : 1
  102. })
  103. const total = computed(() => {
  104. return multipleType
  105. ? (result.value as MultipleResult<ExtractApiResponse<T>>)?.totalCount || 0
  106. : (result.value as Array<any>).length || 0
  107. })
  108. const data = computed(() => {
  109. return multipleType
  110. ? (result.value as MultipleResult<ExtractMultipleApiResponse<T>>)?.result || []
  111. : (unref(result) as any)
  112. })
  113. const pagination = computed(() => {
  114. return Object.assign(DEFAULT_PAGINATION, {
  115. pageSize: baseParams.pageSize,
  116. pageCount: pageCount.value,
  117. total: total.value,
  118. })
  119. })
  120. return {
  121. tableRef,
  122. elTableRef,
  123. hasSelected,
  124. onSectionChange,
  125. fetchTable,
  126. selectedList,
  127. loading,
  128. total,
  129. data,
  130. pagination,
  131. currentPage: currentPage,
  132. error,
  133. }
  134. }
  135. export default useTable