70 lines
1.6 KiB
TypeScript
70 lines
1.6 KiB
TypeScript
"use client"
|
|
import { useCallback, useEffect, useState } from "react"
|
|
import { toast } from "sonner"
|
|
import { useStatus } from "@/hooks/data"
|
|
import type { ApiResponse, PageRecord } from "@/lib/api"
|
|
|
|
export function useDataTable<T>(
|
|
fetch: (page: number, size: number) => Promise<ApiResponse<PageRecord<T>>>,
|
|
) {
|
|
const [status, setStatus] = useStatus()
|
|
|
|
const [data, setData] = useState<T[]>([])
|
|
const [page, setPage] = useState(1)
|
|
const [size, setSize] = useState(10)
|
|
const [total, setTotal] = useState(0)
|
|
|
|
const _refresh = useCallback(
|
|
async (_page: number, _size: number) => {
|
|
setStatus("load")
|
|
try {
|
|
const resp = await fetch(_page, _size)
|
|
if (!resp.success) {
|
|
throw new Error("获取数据失败")
|
|
}
|
|
|
|
setData(resp.data.list)
|
|
setPage(resp.data.page)
|
|
setSize(resp.data.size)
|
|
setTotal(resp.data.total)
|
|
|
|
setStatus("done")
|
|
} catch (error) {
|
|
toast.error(error instanceof Error ? error.message : "未知错误")
|
|
setStatus("fail")
|
|
}
|
|
},
|
|
[fetch, setStatus],
|
|
)
|
|
|
|
const onPageChange = useCallback(
|
|
(page: number) => _refresh(page, size),
|
|
[_refresh, size],
|
|
)
|
|
|
|
const onSizeChange = useCallback(
|
|
(size: number) => _refresh(1, size),
|
|
[_refresh],
|
|
)
|
|
|
|
useEffect(() => {
|
|
_refresh(1, size)
|
|
}, [_refresh, size])
|
|
|
|
return {
|
|
data,
|
|
status,
|
|
setStatus,
|
|
pagination: {
|
|
page,
|
|
size,
|
|
total,
|
|
onPageChange,
|
|
onSizeChange,
|
|
},
|
|
refresh: (_page?: number, _size?: number) => {
|
|
_refresh(_page ?? page, _size ?? size)
|
|
},
|
|
}
|
|
}
|