import { Table, TableExpose } from '@/components/Table' import { ElTable, ElMessageBox, ElMessage } from 'element-plus' import { ref, reactive, watch, computed, unref, nextTick } from 'vue' import { get } from 'lodash-es' import type { TableProps } from '@/components/Table/src/types' import { useI18n } from '@/hooks/web/useI18n' import { TableSetPropsType } from '@/types/table' import { columns } from 'element-plus/es/components/table-v2/src/common' const { t } = useI18n() interface TableResponse { count: number data: T[] } interface UseTableConfig { getListApi: (option: any) => Promise>> delListApi?: (option: any) => Promise exportQueryListApi?: (params: any, data: any) => Promise // 返回数据格式配置 response: { data: string count?: string } props?: TableProps } interface TableObject { limit: number page: number count: number tableData: T[] params: any loading: boolean currentRow: Nullable } export const useTable = (config?: UseTableConfig) => { const tableObject = reactive>({ // 页数 limit: 10, // 当前页 page: 1, // 总条数 count: 10, // 表格数据 tableData: [], // AxiosConfig 配置 params: {}, // 加载中 loading: true, // 当前行的数据 currentRow: null }) const paramsObj = computed(() => { return { ...tableObject.params, limit: tableObject.limit, page: tableObject.page } }) watch( () => tableObject.page, () => { methods.getList() } ) watch( () => tableObject.limit, () => { // 当前页不为1时,修改页数后会导致多次调用getdata方法 if (tableObject.page === 1) { methods.getList() } else { tableObject.page = 1 methods.getList() } } ) // Table实例 const tableRef = ref() // ElTable实例 const elTableRef = ref>() const register = (ref: typeof Table & TableExpose, elRef: ComponentRef) => { tableRef.value = ref elTableRef.value = unref(elRef) } const getTable = async () => { await nextTick() const table = unref(tableRef) if (!table) { console.error('The table is not registered. Please use the register method to register') } return table } const delData = async (ids: string[] | number[]) => { if (config?.delListApi) { const res = await config.delListApi(ids) if (res) { ElMessage.success(t('common.delSuccess')) methods.getList() } } else { ElMessage.error('删除失败,请配置删除接口!') } } const methods = { getList: async () => { tableObject.loading = true const res = await config?.getListApi(unref(paramsObj)).finally(() => { tableObject.loading = false }) if (res) { tableObject.tableData = get(res || {}, config?.response.data as string) tableObject.count = get(res || {}, config?.response.count as string) || 0 } }, setProps: async (props: TableProps = {}) => { const table = await getTable() table?.setProps(props) }, setColumn: async (columnProps: TableSetPropsType[]) => { const table = await getTable() table?.setColumn(columnProps) }, getSelections: async () => { const table = await getTable() return (table?.selections || []) as T[] }, // 与Search组件结合 setSearchParams: (data: Recordable) => { tableObject.page = 1 tableObject.params = Object.assign(tableObject.params, { limit: tableObject.limit, page: tableObject.page, ...data }) methods.getList() }, // 删除数据 delListApi: async (ids: string[] | number[], multiple: boolean, message = true) => { const tableRef = await getTable() if (multiple) { if (!tableRef?.selections.length) { ElMessage.warning(t('common.delNoData')) return } } else { if (!tableObject.currentRow) { ElMessage.warning(t('common.delNoData')) return } } if (message) { ElMessageBox.confirm(t('common.delMessage'), t('common.delWarning'), { confirmButtonText: t('common.delOk'), cancelButtonText: t('common.delCancel'), type: 'warning' }).then(async () => { await delData(ids) }) } else { await delData(ids) } }, // 导出筛选列表 exportQueryList: async () => { if (config?.exportQueryListApi) { const header = config?.props?.columns ?.filter((item) => item.show === true) .map((item) => { return { field: item.field, label: item.label } }) tableObject.loading = true const res = await config?.exportQueryListApi(unref(paramsObj), header).finally(() => { tableObject.loading = false }) if (res) { const a = document.createElement('a') a.style.display = 'none' a.href = res.data.url a.target = '_blank' a.download = res.data.filename const event = new MouseEvent('click') a.dispatchEvent(event) } } else { ElMessage.error('删除失败,请配置删除接口!') } } } config?.props && methods.setProps(config.props) return { register, elTableRef, tableObject, methods } }