zy-react-library/hooks/useTable/index.js

163 lines
5.1 KiB
JavaScript
Raw Normal View History

2025-10-22 14:43:42 +08:00
import { tools } from "@cqsjjb/jjb-common-lib";
import { useAntdTable } from "ahooks";
const { query } = tools.router;
/**
* 获取数据
*/
function getService(service, getExtraParams = {}, transform) {
// 获取额外的参数
const extraParams = (typeof getExtraParams === "function" ? getExtraParams() : getExtraParams) || {};
// 获取数据
return async ({ current, pageSize }, formData = {}) => {
// 如果提供了 transform 函数,则在请求之前调用它
let transformedFormData = formData;
if (typeof transform === "function") {
const transformResult = transform(formData);
// 如果 transform 函数有返回值则将其与原始表单数据合并transform 的优先级更高
if (transformResult && typeof transformResult === "object") {
transformedFormData = { ...formData, ...transformResult };
}
}
// 发起请求
const res = await service({
pageIndex: current,
pageSize,
...transformedFormData,
...extraParams,
});
// 返回数据
return {
list: res.data || [],
total: res.totalCount || 0,
...res,
};
};
}
/**
* 将搜索表单项和分页参数保存到 URL
*/
function setQuery(searchForm, pagination) {
// 将对象转换为键值对字符串格式
const getJoinString = (data) => {
const keys = [];
const values = [];
Object.entries(data).forEach(([key, value]) => {
if (value) {
keys.push(key);
if (Array.isArray(value)) {
// 数组值使用方括号包裹,并用竖线分隔
values.push(`[${value.join("|")}]`);
}
else {
values.push(value);
}
}
});
return { keys: keys.join(","), values: values.join(",") };
};
// 获取搜索表单和分页数据的键值对字符串
const searchFormData = getJoinString(searchForm);
const paginationData = getJoinString(pagination);
// 将数据存储到 URL 查询参数中
query.searchFormKeys = searchFormData.keys;
query.searchFormValues = searchFormData.values;
query.paginationKeys = paginationData.keys;
query.paginationValues = paginationData.values;
}
/**
* URL 中获取查询参数
*/
function getQuery(keysStr, valuesStr) {
// 将键值字符串分割为数组
const keys = keysStr ? keysStr.split(",") : [];
const values = valuesStr ? valuesStr.split(",") : [];
// 构建结果对象
const resultMap = {};
keys.forEach((key, index) => {
if (values[index]) {
// 处理数组值(方括号包裹的值)
if (values[index].startsWith("[") && values[index].endsWith("]")) {
const arrayContent = values[index].substring(1, values[index].length - 1);
resultMap[key] = arrayContent ? arrayContent.split("|") : [];
}
else {
// 处理普通值
resultMap[key] = values[index];
}
}
});
return resultMap;
}
/**
* 自定义 useTable继承 ahooks useAntdTable根据需求进行扩展
*/
function useTable(service, options) {
// 获取额外参数和转换函数
const { params: extraParams, transform, ...restOptions } = options || {};
// 获取配置项
const {
useStorageQueryCriteria = true,
usePagination = true,
defaultType = "advance",
defaultCurrent = 1,
defaultPageSize = 10,
defaultPagination = { current: defaultCurrent, pageSize: defaultPageSize },
...restRestOptions
} = restOptions;
// 获取存储的查询条件
const storageQueryCriteriaSearchForm = useStorageQueryCriteria ? getQuery(query.searchFormKeys, query.searchFormValues) : {};
const storageQueryCriteriaPagination = useStorageQueryCriteria && usePagination ? getQuery(query.paginationKeys, query.paginationValues) : {};
// 确定实际使用的搜索表单和分页参数
const actualSearchForm = Object.keys(storageQueryCriteriaSearchForm).length > 0 ? storageQueryCriteriaSearchForm : {};
/** @type {{current: number, pageSize: number}} */
const actualPagination = usePagination ? Object.keys(storageQueryCriteriaPagination).length > 0 ? storageQueryCriteriaPagination : defaultPagination : {};
// 调用 ahooks 的 useAntdTable
const res = useAntdTable(
getService(service, extraParams, transform),
{
...restRestOptions,
defaultParams: [actualPagination, actualSearchForm],
defaultType,
onSuccess: (data, params) => {
// 执行成功回调,为了保留 ahooks 的 onSuccess 回调
restOptions.onSuccess && restOptions.onSuccess(data, params);
// 存储查询条件和分页到 URL
useStorageQueryCriteria && setQuery(
params[1] ?? {},
usePagination
? { current: res.tableProps.pagination.current, pageSize: res.tableProps.pagination.pageSize }
: {},
);
},
},
);
// 执行回调函数
restOptions.callback && restOptions.callback(res?.data?.list || [], res?.data || {});
// 返回结果
return {
...res,
tableProps: {
...res.tableProps,
pagination: usePagination ? { ...res.tableProps.pagination, showQuickJumper: true, showSizeChanger: true } : false,
},
getData: res.search.submit,
};
}
export default useTable;