import { ref, unref, computed, onMounted } from 'vue' import { isBoolean } from '@/utils/is' import { toTreeData } from './toTree' export function useDataSource(propsRef, { getPaginationInfo, setPagination, setLoading, tableData }, emit) { const dataSourceRef = ref([]) const paginationPage = ref(1) async function fetch(opt) { try { /* 设置loading */ setLoading(true) const { request, pagination, paginationSetting, dataType } = unref(propsRef) /* 无接口请求中断 */ if (!request) return /* 获取分页信息 */ const pageField = paginationSetting.pageField const listPageField = paginationSetting.listPageField const sizeField = paginationSetting.sizeField const totalField = paginationSetting.totalField const listField = paginationSetting.listField let pageParams = {} const { page = 1, pageSize = 10 } = unref(getPaginationInfo) /* 判断是否需要分页信息 */ const noPagination = (isBoolean(pagination) && !pagination) || isBoolean(getPaginationInfo) if (noPagination) { pageParams = {} } else { pageParams[pageField] = (opt && opt[pageField]) || page paginationPage.value = pageParams[pageField] pageParams[sizeField] = pageSize } const params = { ...pageParams } const response = await request(params) const res = noPagination ? response : response.data const resultTotal = res[totalField] || 0 const currentPage = res[listPageField] // 如果数据异常,需获取正确的页码再次执行 if (resultTotal) { if (page > Math.ceil(resultTotal / pageSize)) { setPagination({ [pageField]: Math.ceil(resultTotal / pageSize) }) fetch(opt) } } // 处理数据结构 const resultInfo = res[listField] ? res[listField] : res dataSourceRef.value = dataType === 'tree' ? dealTree(resultInfo.data) : resultInfo setPagination({ [pageField]: currentPage, [totalField]: Math.ceil(resultTotal / pageSize), itemCount: resultTotal }) /* 更新页码数据 */ if (opt && opt[pageField]) { setPagination({ [pageField]: opt[pageField] || 1 }) } emit('fetch-success', { items: unref(resultInfo), resultTotal }) } catch (error) { console.error(error) // emit('fetch-error', error) dataSourceRef.value = [] } finally { setLoading(false) } } /** * 递归遍历数据处理成树形结构 * @returns 返回树形结构数据 */ function dealTree(info) { const tree = toTreeData(info, 'id', 'pid', 'children') return tree } const getDataSourceRef = computed(() => { const dataSource = unref(dataSourceRef) if (!dataSource || dataSource.length === 0) { return unref(dataSourceRef) } return unref(dataSourceRef) }) function getDataSource() { return getDataSourceRef.value } function setTableData(values) { dataSourceRef.value = values } const getRowKey = computed(() => { const { rowKey } = unref(propsRef) return rowKey || (() => { return 'key' }) }) async function reload(opt) { await fetch(opt) } async function reFetch(opt, reload = true) { const { paginationSetting } = unref(propsRef) const pageField = paginationSetting.pageField const sizeField = paginationSetting.sizeField const pageSize = paginationSetting.pageSize setPagination({ [pageField]: reload ? 1 : paginationPage.value, [sizeField]: pageSize }) await fetch(opt) } onMounted(() => { setTimeout(() => { fetch() }, 15) }) return { fetch, getDataSourceRef, getDataSource, setTableData, getRowKey, reload, reFetch } }