163 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
		
			
		
	
	
			163 lines
		
	
	
		
			5.1 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) {
							 | 
						|||
| 
								 | 
							
								  // 获取额外参数和转换函数
							 | 
						|||
| 
								 | 
							
								  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;
							 |