github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/static_source/admin/src/hooks/web/useTableMain.ts (about)

     1  import { Table, TableExpose } from '@/components/Table'
     2  import { ElTable, ElMessageBox, ElMessage } from 'element-plus'
     3  import { ref, reactive, watch, computed, unref, nextTick } from 'vue'
     4  import { get } from 'lodash-es'
     5  import type { TableProps } from '@/components/Table/src/types'
     6  import { useI18n } from '@/hooks/web/useI18n'
     7  import { TableSetPropsType } from '@/types/table'
     8  import {ApiMeta} from "@/api/stub";
     9  
    10  const { t } = useI18n()
    11  
    12  interface TableResponse<T = any> {
    13    items: T[]
    14    meta?: ApiMeta;
    15  }
    16  
    17  interface UseTableConfig<T = any> {
    18    getListApi: (option: any) => Promise<IResponse<TableResponse<T>>>
    19    delListApi?: (option: any) => Promise<IResponse>
    20    // 返回数据格式配置
    21    response: {
    22      items: T[]
    23      meta?: ApiMeta;
    24    }
    25    // 默认传递的参数
    26    defaultParams?: Recordable
    27    props?: TableProps
    28  }
    29  
    30  interface TableObject<T = any> {
    31    pageSize: number
    32    currentPage: number
    33    total: number
    34    tableList: T[]
    35    params: any
    36    loading: boolean
    37    currentRow: Nullable<T>
    38  }
    39  
    40  export const useTable = <T = any>(config?: UseTableConfig<T>) => {
    41    const tableObject = reactive<TableObject<T>>({
    42      // 页数
    43      pageSize: 2,
    44      // 当前页
    45      currentPage: 1,
    46      // 总条数
    47      total: 10,
    48      // 表格数据
    49      tableList: [],
    50      // AxiosConfig 配置
    51      params: {
    52        ...(config?.defaultParams || {})
    53      },
    54      // 加载中
    55      loading: true,
    56      // 当前行的数据
    57      currentRow: null
    58    })
    59  
    60    const paramsObj = computed(() => {
    61      return {
    62        ...tableObject.params,
    63        limit: tableObject.pageSize,
    64        page: tableObject.currentPage
    65      }
    66    })
    67  
    68    watch(
    69      () => tableObject.currentPage,
    70      () => {
    71        methods.getList()
    72      }
    73    )
    74  
    75    watch(
    76      () => tableObject.pageSize,
    77      () => {
    78        // 当前页不为1时,修改页数后会导致多次调用getList方法
    79        if (tableObject.currentPage === 1) {
    80          methods.getList()
    81        } else {
    82          tableObject.currentPage = 1
    83          methods.getList()
    84        }
    85      }
    86    )
    87  
    88    // Table实例
    89    const tableRef = ref<typeof Table & TableExpose>()
    90  
    91    // ElTable实例
    92    const elTableRef = ref<ComponentRef<typeof ElTable>>()
    93  
    94    const register = (ref: typeof Table & TableExpose, elRef: ComponentRef<typeof ElTable>) => {
    95      tableRef.value = ref
    96      elTableRef.value = unref(elRef)
    97    }
    98  
    99    const getTable = async () => {
   100      await nextTick()
   101      const table = unref(tableRef)
   102      if (!table) {
   103        console.error('The table is not registered. Please use the register method to register')
   104      }
   105      return table
   106    }
   107  
   108    const delData = async (ids: string[] | number[]) => {
   109      const res = await (config?.delListApi && config?.delListApi(ids))
   110      if (res) {
   111        ElMessage.success(t('common.delSuccess'))
   112  
   113        // 计算出临界点
   114        const currentPage =
   115          tableObject.total % tableObject.pageSize === ids.length || tableObject.pageSize === 1
   116            ? tableObject.currentPage > 1
   117              ? tableObject.currentPage - 1
   118              : tableObject.currentPage
   119            : tableObject.currentPage
   120  
   121        tableObject.currentPage = currentPage
   122        methods.getList()
   123      }
   124    }
   125  
   126    const methods = {
   127      getList: async () => {
   128        tableObject.loading = true
   129        const res = await config?.getListApi(unref(paramsObj)).finally(() => {
   130          tableObject.loading = false
   131        })
   132        if (res) {
   133          tableObject.tableList = get(res.data || {}, config?.response.list as string)
   134          tableObject.total = get(res.data || {}, config?.response?.total as string) || 0
   135        }
   136      },
   137      setProps: async (props: TableProps = {}) => {
   138        const table = await getTable()
   139        table?.setProps(props)
   140      },
   141      setColumn: async (columnProps: TableSetPropsType[]) => {
   142        const table = await getTable()
   143        table?.setColumn(columnProps)
   144      },
   145      getSelections: async () => {
   146        const table = await getTable()
   147        return (table?.selections || []) as T[]
   148      },
   149      // 与Search组件结合
   150      setSearchParams: (data: Recordable) => {
   151        tableObject.currentPage = 1
   152        tableObject.params = Object.assign(tableObject.params, {
   153          pageSize: tableObject.pageSize,
   154          pageIndex: tableObject.currentPage,
   155          ...data
   156        })
   157        methods.getList()
   158      },
   159      // 删除数据
   160      delList: async (ids: string[] | number[], multiple: boolean, message = true) => {
   161        const tableRef = await getTable()
   162        if (multiple) {
   163          if (!tableRef?.selections.length) {
   164            ElMessage.warning(t('common.delNoData'))
   165            return
   166          }
   167        } else {
   168          if (!tableObject.currentRow) {
   169            ElMessage.warning(t('common.delNoData'))
   170            return
   171          }
   172        }
   173        if (message) {
   174          ElMessageBox.confirm(t('common.delMessage'), t('common.delWarning'), {
   175            confirmButtonText: t('common.delOk'),
   176            cancelButtonText: t('common.delCancel'),
   177            type: 'warning'
   178          }).then(async () => {
   179            await delData(ids)
   180          })
   181        } else {
   182          await delData(ids)
   183        }
   184      }
   185    }
   186  
   187    config?.props && methods.setProps(config.props)
   188  
   189    return {
   190      register,
   191      elTableRef,
   192      tableObject,
   193      methods
   194    }
   195  }