2026-04-02 13:13:59 +08:00
|
|
|
import { useCallback, useState } from "react"
|
2026-01-06 14:57:55 +08:00
|
|
|
import { toast } from "sonner"
|
2026-01-09 18:36:08 +08:00
|
|
|
import type { useDataTable } from "@/components/data-table"
|
2026-01-06 14:57:55 +08:00
|
|
|
import type { ApiResponse } from "@/lib/api"
|
2025-12-29 18:01:16 +08:00
|
|
|
|
|
|
|
|
export function useStatus() {
|
|
|
|
|
return useState<"load" | "fail" | "done">("load")
|
|
|
|
|
}
|
2026-01-06 14:57:55 +08:00
|
|
|
|
|
|
|
|
export function useFetch<TArgs extends unknown[], TResult>(
|
2026-01-09 18:36:08 +08:00
|
|
|
table: ReturnType<typeof useDataTable>,
|
2026-01-06 14:57:55 +08:00
|
|
|
fetchData: (...args: TArgs) => Promise<ApiResponse<TResult>>,
|
|
|
|
|
messages: {
|
|
|
|
|
done?: string
|
|
|
|
|
fail?: string
|
|
|
|
|
},
|
|
|
|
|
) {
|
|
|
|
|
return useCallback(
|
|
|
|
|
async (...args: TArgs) => {
|
|
|
|
|
try {
|
2026-01-09 18:36:08 +08:00
|
|
|
table.setStatus?.("load")
|
2026-01-06 14:57:55 +08:00
|
|
|
const resp = await fetchData(...args)
|
|
|
|
|
if (!resp.success) {
|
|
|
|
|
throw new Error(resp.message)
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-09 18:36:08 +08:00
|
|
|
table.setStatus?.("done")
|
|
|
|
|
table.refresh(table.pagination.page, table.pagination.size)
|
2026-01-06 14:57:55 +08:00
|
|
|
toast.success(messages.done || "获取数据成功")
|
|
|
|
|
} catch (e) {
|
2026-01-09 18:36:08 +08:00
|
|
|
table.setStatus?.("fail")
|
2026-01-06 14:57:55 +08:00
|
|
|
toast.error(messages.fail || "获取数据失败", {
|
|
|
|
|
description: (e as Error).message || "未知错误",
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
2026-01-09 18:36:08 +08:00
|
|
|
[
|
|
|
|
|
fetchData,
|
|
|
|
|
table.setStatus,
|
|
|
|
|
table.pagination.page,
|
|
|
|
|
table.pagination.size,
|
|
|
|
|
table.refresh,
|
|
|
|
|
messages,
|
|
|
|
|
],
|
2026-01-06 14:57:55 +08:00
|
|
|
)
|
|
|
|
|
}
|
2026-03-23 17:49:47 +08:00
|
|
|
|
|
|
|
|
type Action = <P extends unknown[], R>(...args: P) => Promise<R>
|
|
|
|
|
|
|
|
|
|
export function useAction(action: Action) {
|
|
|
|
|
const [status, setStatus] = useStatus()
|
|
|
|
|
const func = useCallback(
|
|
|
|
|
async (...args: Parameters<Action>) => {
|
|
|
|
|
try {
|
|
|
|
|
setStatus("load")
|
|
|
|
|
await action(...args)
|
|
|
|
|
setStatus("done")
|
|
|
|
|
} catch (e) {
|
|
|
|
|
setStatus("fail")
|
|
|
|
|
throw e
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
[action, setStatus],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return [func, status]
|
|
|
|
|
}
|