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