import { useState, useCallback, useEffect } from 'react'; import type { BasePaginatedOptions, PaginatedOptionsWithFormat, } from '@umijs/use-request/lib/types'; import omit from 'omit.js' import useUpdateEffect from '@umijs/hooks/lib/useUpdateEffect'; export interface Store { [name: string]: any; } export interface UseAntdTableFormUtils { getFieldInstance?: (name: string) => {}; // antd 3 setFieldsValue: (value: Store) => void; getFieldsValue: (...args: any) => Store; resetFields: (...args: any) => void; [key: string]: any; } export interface BaseOptions<U> extends Omit<BasePaginatedOptions<U>, 'paginated'> { form: UseAntdTableFormUtils; } export interface OptionsWithFormat<R, Item, U> extends Omit<PaginatedOptionsWithFormat<R, Item, U>, 'paginated'> { form: UseAntdTableFormUtils; } function handleArray(key: string, formValue: Store) { const keys = key.split('-'); const values = formValue[key]; const formData = formValue; // && (Array.isArray(values) && values.length === keys.length) || values 日期可能清除为 null if (keys.length > 1) { keys.forEach((element, index) => { if (values === null || values === undefined || values === "") { delete formData[element] } else { const val = values && values[index]; // eslint-disable-next-line no-underscore-dangle formData[element] = val && (val._isAMomentObject ? val.valueOf() : val) || null; } }); delete formData[key]; } if (values === null || values === undefined) { delete formData[key]; } } function handleValue(formData: Store) { const data = formData; // {...formData}; const keys: string[] = Object.keys(data); keys.forEach((element: string) => { handleArray(element, data); }); // for (const key in data) { // handleArray(key, data); // } return data; } function useFormTable<R = any, Item = any, U extends Item = any>( service: (P: any) => void, options: BaseOptions<U> | OptionsWithFormat<R, Item, U>, submitHandle?: () => void, ): any { const { form, ...restOptions } = options; const [type, setType] = useState('simple'); // 全量 form 数据,包括 simple 和 advance const [allFormData, setAllFormData] = useState<Store>({}); // 获取当前展示的 form 字段值 const getActivetFieldValues = useCallback((): Store => { return form.getFieldsValue(null, () => true); }, [form]); /* 初始化,或改变了 searchType, 恢复表单数据 */ useUpdateEffect(() => { form.setFieldsValue(allFormData); }, [type]); const changeType = useCallback(() => { const currentFormData = getActivetFieldValues(); setAllFormData({ ...allFormData, ...currentFormData }); const targetType = type === 'simple' ? 'advance' : 'simple'; setType(targetType); }, [type, allFormData, getActivetFieldValues]); const submit = useCallback((e?: any) => { let params = {}; if (e?.preventDefault) { e.preventDefault(); } else { params = e || params; } setTimeout(() => { const activeFormData = getActivetFieldValues(); // 记录全量数据 const innerAllFormData = { ...allFormData, pageNumber: 1, pageSize: 10, ...activeFormData, ...params }; setAllFormData(innerAllFormData); service(handleValue(innerAllFormData)); if (submitHandle) submitHandle(); }); }, [getActivetFieldValues, allFormData, type]); // 首次加载,手动提交。为了拿到 form 的 initial values useEffect(() => { // 如果有缓存,则使用缓存,重新请求 if(!restOptions?.manual){ form.setFieldsValue(restOptions); submit(restOptions); } }, []); const refresh = useCallback(() => { service(handleValue(allFormData)); }, [type, allFormData, getActivetFieldValues]); const reset = useCallback(() => { form.resetFields(); submit(); }, [form, submit]); const resetSearch = useCallback((e: any) => { form.resetFields(); setAllFormData({}); submit(e); }, [form, submit]); return { tableProps: { onChange: (pagination: any, filters: any, sorter: any) => { const innerAllFormData = { ...allFormData, pageNumber: pagination?.current, pageSize: pagination?.pageSize }; setAllFormData(innerAllFormData); service(handleValue(innerAllFormData)) console.log(filters) console.log(sorter) } }, search: { submit, refresh, data: allFormData, type, changeType, reset, resetSearch } } } export default useFormTable;