feat(web): useApiRequest 添加 loading + usePaginatedData 泛型筛选

- useApiRequest 新增 loading 状态,execute 自动管理 loading 生命周期
- usePaginatedData 支持泛型筛选参数 (filters: F),函数重载保持旧签名兼容
- 新增 filters/setFilters 状态,fetchFn 调用时传入当前 filters
- 向后兼容:旧调用点无需修改
This commit is contained in:
iven
2026-04-27 20:26:00 +08:00
parent 22ef5b6d1f
commit fdceed7284
2 changed files with 54 additions and 25 deletions

View File

@@ -1,4 +1,4 @@
import { useCallback } from 'react';
import { useCallback, useState } from 'react';
import { message } from 'antd';
function extractErrorMessage(err: unknown): string {
@@ -10,12 +10,20 @@ function extractErrorMessage(err: unknown): string {
return '';
}
export function useApiRequest() {
interface UseApiRequestReturn {
execute: <T>(fn: () => Promise<T>, successMsg?: string, errorMsg?: string) => Promise<T | null>;
loading: boolean;
}
export function useApiRequest(): UseApiRequestReturn {
const [loading, setLoading] = useState(false);
const execute = useCallback(async <T>(
fn: () => Promise<T>,
successMsg?: string,
errorMsg = '操作失败',
): Promise<T | null> => {
setLoading(true);
try {
const result = await fn();
if (successMsg) message.success(successMsg);
@@ -24,8 +32,10 @@ export function useApiRequest() {
const msg = extractErrorMessage(err);
message.error(msg || errorMsg);
return null;
} finally {
setLoading(false);
}
}, []);
return { execute };
return { execute, loading };
}