166 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
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) {
 | 
						||
  if (!service)
 | 
						||
    throw new Error("请传入 service");
 | 
						||
 | 
						||
  // 获取额外参数和转换函数
 | 
						||
  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;
 |