193 lines
4.8 KiB
Plaintext
193 lines
4.8 KiB
Plaintext
import { ref, ComputedRef, unref, computed, onMounted, watchEffect, watch } from 'vue';
|
|
import type { BasicTableProps, SorterResult } from '../types/table';
|
|
import type { PaginationProps } from '../types/pagination';
|
|
import { isFunction, isBoolean } from '@/utils/is';
|
|
import { APISETTING, DEFAULTPAGESIZE } from '../const';
|
|
|
|
export function useDataSource(
|
|
propsRef: ComputedRef<BasicTableProps>,
|
|
{ getPaginationInfo, setPagination, setLoading, tableData },
|
|
emit,
|
|
) {
|
|
const dataSourceRef = ref<Recordable[]>([]);
|
|
|
|
watchEffect(() => {
|
|
tableData.value = unref(dataSourceRef);
|
|
});
|
|
|
|
watch(
|
|
() => unref(propsRef).dataSource,
|
|
() => {
|
|
const { dataSource, request }: any = unref(propsRef);
|
|
!request && dataSource && (dataSourceRef.value = dataSource);
|
|
},
|
|
{
|
|
immediate: true,
|
|
},
|
|
);
|
|
|
|
const getRowKey = computed(() => {
|
|
const { rowKey }: any = unref(propsRef);
|
|
return rowKey
|
|
? rowKey
|
|
: () => {
|
|
return 'key';
|
|
};
|
|
});
|
|
|
|
const getDataSourceRef = computed(() => {
|
|
const dataSource = unref(dataSourceRef);
|
|
if (!dataSource || dataSource.length === 0) {
|
|
return unref(dataSourceRef);
|
|
}
|
|
return unref(dataSourceRef);
|
|
});
|
|
|
|
function tableChange(
|
|
pagination: PaginationProps,
|
|
filters?: Partial<Recordable<string[]>>,
|
|
sorter?: SorterResult,
|
|
) {
|
|
const { sortFn, filterFn } = unref(propsRef);
|
|
|
|
setPagination(pagination);
|
|
|
|
const params: Recordable = {};
|
|
if (sorter && isFunction(sortFn)) {
|
|
const sortInfo = sortFn(sorter);
|
|
params.sortInfo = sortInfo;
|
|
}
|
|
|
|
if (filters && isFunction(filterFn)) {
|
|
const filterInfo = filterFn(filters);
|
|
params.filterInfo = filterInfo;
|
|
}
|
|
fetch(params);
|
|
}
|
|
|
|
async function fetch(opt?, isRestReload?) {
|
|
try {
|
|
setLoading(true);
|
|
const { request, pagination }: any = unref(propsRef);
|
|
if (!request) return;
|
|
//组装分页信息
|
|
const pageField = APISETTING.pageField;
|
|
const sizeField = APISETTING.sizeField;
|
|
const totalField = APISETTING.totalField;
|
|
const listField = APISETTING.listField;
|
|
const itemCount = APISETTING.countField;
|
|
let pageParams = {};
|
|
const { current = 1, pageSize = DEFAULTPAGESIZE } = unref(
|
|
getPaginationInfo,
|
|
) as PaginationProps;
|
|
|
|
if ((isBoolean(pagination) && !pagination) || isBoolean(getPaginationInfo)) {
|
|
pageParams = {};
|
|
} else {
|
|
pageParams[pageField] = (opt && opt[pageField]) || current;
|
|
pageParams[sizeField] = pageSize;
|
|
}
|
|
|
|
const params = {
|
|
...pageParams,
|
|
...pagination,
|
|
...opt,
|
|
};
|
|
|
|
//如果是重置刷新,重置页码
|
|
if (isRestReload) {
|
|
params[pageField] = 1;
|
|
setPagination({
|
|
current: 1,
|
|
});
|
|
}
|
|
const res = await request(params);
|
|
const resultTotal = res[totalField] || 0;
|
|
const currentPage = res['current'];
|
|
const total = res[itemCount] || 0;
|
|
const results = res[listField] ? res[listField] : [];
|
|
|
|
// 如果数据异常,需获取正确的页码再次执行
|
|
if (resultTotal) {
|
|
const currentTotalPage = Math.ceil(total / pageSize);
|
|
if (current > currentTotalPage) {
|
|
setPagination({
|
|
current: currentTotalPage,
|
|
[itemCount]: total,
|
|
});
|
|
return await fetch(opt);
|
|
}
|
|
}
|
|
|
|
dataSourceRef.value = results;
|
|
setPagination({
|
|
// [pageField]: currentPage,
|
|
current: currentPage,
|
|
[totalField]: resultTotal,
|
|
[itemCount]: total,
|
|
});
|
|
if (opt && currentPage) {
|
|
setPagination({
|
|
current: currentPage || 1,
|
|
});
|
|
}
|
|
emit('fetch-success', {
|
|
items: unref(results),
|
|
resultTotal,
|
|
});
|
|
} catch (error) {
|
|
console.error(error);
|
|
const totalField = APISETTING.totalField;
|
|
emit('fetch-error', error);
|
|
dataSourceRef.value = [];
|
|
setPagination({
|
|
[totalField]: 0,
|
|
});
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
setTimeout(() => {
|
|
fetch();
|
|
}, 16);
|
|
});
|
|
|
|
function setTableData<T = Recordable>(values: T[]) {
|
|
dataSourceRef.value = values;
|
|
}
|
|
|
|
function getDataSource<T = Recordable>() {
|
|
return getDataSourceRef.value as T[];
|
|
}
|
|
|
|
async function reload(opt?) {
|
|
await fetch(opt);
|
|
}
|
|
|
|
async function restReload(opt?) {
|
|
await fetch(opt, true);
|
|
}
|
|
|
|
async function updateTableData(index: number, key: string, value: any) {
|
|
const record = dataSourceRef.value[index];
|
|
if (record) {
|
|
dataSourceRef.value[index][key] = value;
|
|
}
|
|
return dataSourceRef.value[index];
|
|
}
|
|
|
|
return {
|
|
fetch,
|
|
getRowKey,
|
|
getDataSourceRef,
|
|
getDataSource,
|
|
tableChange,
|
|
setTableData,
|
|
reload,
|
|
restReload,
|
|
updateTableData,
|
|
};
|
|
}
|