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;