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;
 |