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

163 lines
5.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;